Fail to verify certificate in development update calls

I am using localhost subdomains in development, so my URLs look like this: http://ryjl3-tyaaa-aaaaa-aaaba-cai.localhost:8000/

I need to do this to use ES modules natively while in development, because native ES modules do not set the Referer properly for the IC (there is no canisterId query parameter).

This has been working fine so far, but I just tried to do an update call for the first time from the frontend, and I keep getting this error message in response:

  "message": "Fail to verify certificate",
  "stack": "Error: Fail to verify certificate\n    at pollForResponse (http://ryjl3-tyaaa-aaaaa-aaaba-cai.localhost:8000/_snowpack/pkg/@dfinity/agent.js:13815:15)\n    at async caller (http://ryjl3-tyaaa-aaaaa-aaaba-cai.localhost:8000/_snowpack/pkg/@dfinity/agent.js:14000:35)\n    at async graphQLFetcher (http://ryjl3-tyaaa-aaaaa-aaaba-cai.localhost:8000/:39:21)"

I assume this is because I am using localhost subdomains, and the certificate verification process is not looking for that…perhaps?

More information about why I am using localhost subdomains: How does replica know which canister to serve from - #9 by nomeata

1 Like

I’m pretty sure that this is caused by the new update that hardcodes the mainnet rootkey into the HttpAgent. After initializing, you can call agent.fetchRootKey() to use the signature of your local replica.

We have an open improvement item to automatically do this during local development, and I apologize for pushing that responsibility out onto the developer in the meantime


This worked! Thank you

Note that ideally you should not be calling .fetchRootKey() in the production build that you upload to the Internet Computer, else you lose the security properties of update call repsonses, i.e. a man-in-the-middle attack could forge the certificates.


Duly noted, thank you

Where should we put this call if we are running the local identity service? This is what I’m running into with Running locally: Fail to verify certificate · Issue #291 · dfinity/internet-identity · GitHub

I stuck it a couple of places in iiConnection.ts. Looks like it is routed around in prod and for some reason, the identity project builds in production mode.

I’m not sure what your code looks like, but I put the call (it’s asynchronous so make sure to wait for the promise to resolve) before my own update call

Where we should call agent.fetchRootKey() kyle ?

import { Actor, HttpAgent } from ‘@dfinity/agent’;
import { idlFactory as hello_idl, canisterId as hello_id } from ‘dfx-generated/hello’;

const agent = new HttpAgent();

const hello = Actor.createActor(hello_idl, { agent, canisterId: hello_id });

document.getElementById(“clickMeBtn”).addEventListener(“click”, async () => {
const name = document.getElementById(“name”).value.toString();
const greeting = await hello.greet(name);

document.getElementById(“greeting”).innerText = greeting;

Still throwing the same erro

Kindly reply

Try downgrading the @dfinity/agent package to 0.8.0 in your package.json.
I have no idea of what is happening, I just know that it solved this error for me.


Thanks seb. Let me try that.

Sorry for the delay here - I’ve been really focused on upgrading DFX and improving the starter code.

My recommendation is now to try upgrading!

DFX_VERSION="0.7.7" sh -ci "$(curl -fsSL" along with js-agent 0.9.2 should be working fine, without needing to worry about calling the certificate anymore.


FYI still got the error even though I am using sdk v0.7.7 and js-agent v0.9.2

If anybody had trouble running the whoami demo as described here Integrating with Internet Identity | Kyle Peacock's website locally I got It working with this:

as noted in the blogpost you need to add:

identityProvider: "http://localhost:8000?canisterId=LOCAL_INTERNET_IDENITY_CANISTER_ID"

to the authclient.login() argument

I also added:



const agent = new HttpAgent({ identity });

in the handleAuthenticated function

furthermore I updated @dfinity/agent to 0.9.2 in the devdependencies and used dfx 0.7.7

and added a .env file in the auth-client-demo repo with CANISTER_ID=YOUR_WHOAMI_CANISTER_ID

good luck!

Take care not to use fetchRootKey() in production here, also if the project is updated to use 0.7.7 this should be taken care of for you in the canister’s generated js file, so you shouldn’t need to add it yourself.

It didn’t work locally for me without the fetchRootKey() but maybe I did something wrong.

EDIT: this is probably because the web-auth-demo was still made for 0.7.2 be sure to check out this post Dfx 0.7.7 Changes | Kyle Peacock's website

1 Like

I’ve updated the auth-client demo to 0.8.0 GitHub - krpeacock/auth-client-demo: Example demo of how to use to make authenticated calls to an IC app. Still need to go back and make adjustments to the blog post, but I wanted the reference to be out there.

If you’ve already run it before, I recommend resetting things with git clean -dfx and then following the README directions

1 Like

So I’m starting to get this exact error now Error: Fail to verify certificate in React Native. I’m pretty sure it worked 2 months ago when I last enabled BLS signature validation. (I disabled it for the last 2 months until today, when I wanted to test it out again.)

FYI I’m on dfx 0.7.1, and I do call await agent.fetchRootKey before making an update call.

I’m also NOT using Internet Identity, and instead use an Identity that I construct from a private key that I get from a 3rd party, but it also doesn’t work with the AnonymousIdentity. Here’s the code where I construct the Actor:

function createActor(identity?: Identity) {
  const agent = new HttpAgent({host: getHost(), identity});
  const actor = Actor.createActor<_SERVICE>(service_idl, {
    canisterId: service_id,
  return {agent, actor};

Also, I put a bunch of console.log statements in the verify function in the agent-js library, and it says that…

 LOG  rootHash: []
 LOG  derKey: []
 LOG  sig: [167, 104, 28, 190, 58, 122, 182, 218, 25, 197, 15, 41, 232, 84, 122, 112, 103, 42, 241, 195, 71, 163, 225, 88, 13, 144, 164, 240, 75, 252, 45, 115, 136, 200, 246, 201, 187, 175, 115, 57, 69, 220, 220, 245, 52, 211, 89, 23]
 LOG  key: []
 LOG  msg: []

Is it normal for everything but sig to be empty?


OK I identified the root cause.

Upgrading agent-js from 0.9.1 to 0.10.1 caused certificate validation to fail. I think it’s due to the removal of Buffer in favor of ArrayBuffer.

@kpeacock, have you seen this before? When I revert my code from 0.10.1 to 0.9.1, the BLS signature verification passes.