demo · v135

SecurityError → NotAllowedError

Chrome 135 changes the error type thrown by payment WebAuthn credential creation in the activationless iframe envelope. The legacy payment path threw SecurityError; the aligned path throws NotAllowedError, matching WebAuthn's missing-activation failure.

WebAuthn: probing…

before chrome 135

payment create() without a gesture rejected with DOMException, name: "SecurityError".

chrome 135+

payment create() without a gesture rejects with DOMException, name: "NotAllowedError" — matching the rest of WebAuthn.

actual result

click a probe button

the code

try {
  await navigator.credentials.create({
    publicKey: {
      rp: { name: "demo" },
      user: { id: new Uint8Array(16), name: "u", displayName: "u" },
      challenge: new Uint8Array(32),
      pubKeyCredParams: [{ type: "public-key", alg: -7 }],
    },
    payment: { isPayment: true },
  });
} catch (e) {
  // chrome <135 : "SecurityError"
  // chrome >=135: "NotAllowedError"
  console.log(e.name);
}

migration impact

Code that only handled SecurityError for payment credential creation can miss the Chrome 135+ activation failure. Keep SecurityError for true policy, origin, or RP ID failures, and route the missing-activation or user-denial path through NotAllowedError.

To inspect the success path, enable a WebAuthn virtual authenticator in DevTools and run the fresh-click probe. Without an authenticator, the page is expected to stay on the error path.

see also