QuantumNous/new-api · error · Error

Failed to complete Passkey login

Error message

Failed to complete Passkey login

What it means

Thrown in the Passkey sign-in flow when finishPasskeyLogin — the POST that submits the signed WebAuthn assertion with the flow_token — returns success:false without a handled server message key. The fallback text is 'Failed to complete Passkey login'; the server's own message wins when present. This is a server-side verification failure of the assertion.

Source

Thrown at web/src/features/auth/sign-in/components/user-auth-form.tsx:291

      const credential = (await navigator.credentials.get({
        publicKey,
      })) as PublicKeyCredential | null

      if (!credential) {
        toast.info(t('Passkey login was cancelled'))
        return
      }

      const assertion = buildAssertionResult(credential)
      if (!assertion) {
        throw new Error(t('Invalid Passkey response'))
      }

      const finish = await finishPasskeyLogin(flowToken, assertion)
      if (!finish.success) {
        if (getServerErrorMessageKey(finish)) return
        throw new Error(finish.message || t('Failed to complete Passkey login'))
      }

      if (!isAuthBundle(finish.data)) {
        throw new Error(t('Missing user data from Passkey login response'))
      }

      await handleLoginSuccess(finish.data, redirectTo)
      toast.success(t('Signed in with Passkey'))
    } catch (error: unknown) {
      if (getServerErrorMessageKey(error)) return
      if (error instanceof DOMException && error.name === 'NotAllowedError') {
        toast.info(t('Passkey login was cancelled or timed out'))
      } else if (error instanceof Error) {
        toast.error(error.message)
      } else {
        toast.error(t('Passkey login failed'))
      }
    } finally {

View on GitHub (pinned to e2c7aa7b10)

Solutions

  1. Read finish.message from the response — the backend states the verification failure reason.
  2. Retry the whole Passkey flow promptly (fresh challenge + flow_token); most failures are stale-token timing issues.
  3. If it persists for one device, re-register the passkey (delete then add) — server-side credential state may be stale.
  4. Check server logs/clock sync if all users are affected.
Defensive patterns

Strategy: retry

Try / catch

try {
  const finish = await finishPasskeyLogin(flowToken, assertion)
  if (!finish.success) {
    if (getServerErrorMessageKey(finish)) return
    throw new Error(finish.message || t('Failed to complete Passkey login'))
  }
} catch (error) {
  if (getServerErrorMessageKey(error)) return
  if (error instanceof DOMException && error.name === 'NotAllowedError') {
    toast.info(t('Passkey login was cancelled or timed out'))
  } else {
    toast.error(error instanceof Error ? error.message : t('Passkey login failed'))
  }
}

Prevention

When it happens

Trigger: POST finish-passkey-login returns success:false: challenge mismatch, expired flow_token, unknown credential ID, signature verification failure, or clock skew between server and authenticator.

Common situations: User left the WebAuthn prompt open until the flow_token expired; credential deleted server-side but still present in the browser; backend RPC to the WebAuthn verifier failing; server time drift breaking challenge timestamps.

Related errors


AI-assisted analysis of QuantumNous/new-api@e2c7aa7b10 (2026-08-15). Data as JSON: /api/errors/a15392e474ea4694. Report an issue: GitHub.