Error when making HTTP call in Motoko: Canister http responses were different across replicas, and no consensus was reached

I’m attempting to make an authenticated HTTP Post call in Motoko. When I make the HTTP call, the error listed below is thrown. I’ve seen this error previously when attempting to make an HTTP Get call and was able to resolve the error by altering the tranform() function that I designate within the HTTP request so that the headers array is always empty, but that doesn’t seem to be a solution in this case as the error persists. I suspect that my transform function may be the culprit here, but I also wonder if this error could be the result of an improperly generated ECDSA signature when signing the envelope. Below, I’ve also listed the http_request that I’m sending and the transform() function that I’m using. Does anyone see any obvious issues with what I have? or can anyone confirm whether or not this error could come by way of an improperly generated message signature? thank you

Error message that I’m getting:

Call was rejected:
  Request ID: 7a89a2ddb2d271c4199c93daf91b5e388da71af291adf3c7183dbee75767b3fb
  Reject code: 4
  Reject text: Canister http responses were different across replicas, and no consensus was reached

my HTTP request input

let http_request = {
     body = //CBOR encoding of the envelope
     url = //API endpoint where the method I'm calling is found
     headers = [{name = "content-type"; value= "application/cbor"}]
     //transformFn defined below
     transform = ?{ function = transformFn; context = Blob.fromArray([]); };
     method = #post;
     max_response_bytes = ?Nat64.fromNat(1024 * 1024);
};

here is how I defined transformFn:

 public query func transformFn({context: Blob; response: IC.http_response}) : async IC.http_response {
    let transformed : IC.http_response = {
    status = response.status;
    body = response.body;
    headers = [];
  };
  transformed;
};
3 Likes

I think you might need to add an Idempotency-Key header. I haven’t made it this far in practice but I know when I was reading the IC guide for outcalls it says to use idempotency keys

https://internetcomputer.org/docs/current/developer-docs/integrations/https-outcalls/https-outcalls-post#important-notes-on-post-requests

3 Likes

It’s mainly because of your http_post request is getting different responses when multiple replicas hitting same url with same request.

You need to correctly handle the response inside transform function, to make it equal across all replicas, for them to reach the consensus.

2 Likes

How do I go about troubleshooting the issue with my tansform function? I’m not sure what the issue with my transform function might be. Is there any way I could see the the responses that the replicas are sending back? That’d be useful for diagnosing the problem.

1 Like

I would have used postman to check response of http post request.
Try hitting url with same post request multiple times and check what actual difference those responses have in there, and then try to process the post request responses inside transform function accordingly to make them same to reach consensus .
For a good example of processing http request responses inside transform function you can refer to https://github.com/dfinity/exchange-rate-canister/tree/main

Also if you want to try non replicated http outcalls to avoid transform function for fire n forget type of http requests you can also check :
https://forum.dfinity.org/t/non-replicated-https-outcalls/26627

4 Likes

I ended up resolving this error by increasing the ingress_expirey value. I initially had it set to just 5 seconds. Increasing it to 60 seconds resolved the bug.

2 Likes