Skip to content
ecdsa.com
SimpleWebAuthn (@simplewebauthn/server)WebAuthn and passkeys

Error message

Unexpected registration response origin "http://localhost:3000", expected "https://app.example.com"

Also printed as

  • Unexpected authentication response origin "http://localhost:3000", expected "https://app.example.com"
  • Unexpected registration response challenge "b3RoZXI", expected "c2VydmVyLWNoYWxsZW5nZS0xMjM"

The first quoted value is the origin the browser reported, the second your configuration. During sign-in the text says "authentication response"; a mismatched challenge produces "Unexpected registration response challenge …" from the same library.

SimpleWebAuthn (@simplewebauthn/server) — verifyRegistrationResponse / verifyAuthenticationResponse

What it means

The browser recorded the page's origin in `clientDataJSON` (the data the authenticator signs), and it differs from the `expectedOrigin` your server passed to SimpleWebAuthn. The check exists to stop a credential ceremony performed on one site — for example a phishing look-alike — from being accepted by another. Nothing is wrong with the authenticator; the server's notion of where its pages live does not match where the ceremony actually ran.

Why it happens

How to fix it

  1. 1.

    List every legitimate origin explicitly

    `expectedOrigin` accepts an array. Keep it to origins you control; never accept the origin from the request itself.

    js
    const verification = await verifyRegistrationResponse({
      response: body,
      expectedChallenge: session.currentChallenge,
      // Every origin that legitimately hosts your sign-up page, exactly as browsers report it:
      expectedOrigin: ["https://app.example.com", "https://www.example.com"],
      expectedRPID: "example.com",
    });
  2. 2.

    Add the Android app's origin

    Compute the base64url SHA-256 of the app's signing certificate and add it in the `android:apk-key-hash:` form.

    js
    // Android apps report "android:apk-key-hash:<base64url SHA-256 of the app signing certificate>".
    // SHA-256 fingerprint from Play Console or: keytool -list -v -keystore release.jks | grep SHA256
    const fingerprintHex = process.env.ANDROID_SIGNING_CERT_SHA256.replaceAll(":", "");
    const androidOrigin = "android:apk-key-hash:" + Buffer.from(fingerprintHex, "hex").toString("base64url");
    
    const verification = await verifyRegistrationResponse({
      response: body,
      expectedChallenge: session.currentChallenge,
      expectedOrigin: ["https://example.com", androidOrigin],
      expectedRPID: "example.com",
    });

Related errors

Browse the full signature error database