nextauthjs/next-auth · error · AuthError

Missing user registration data in WebAuthn challenge cookie

Error message

Missing user registration data in WebAuthn challenge cookie

What it means

verifyRegister retrieves the stored challenge and user registration data from the WebAuthn challenge cookie via webauthnChallenge.use(). The challenge cookie exists but carries no registerData (user info), so registration cannot know which user to attach the new credential to, and this AuthError is thrown.

Source

Thrown at packages/core/src/lib/utils/webauthn-utils.ts:345

  // Get WebAuthn response from request body
  const data =
    request.body && typeof request.body.data === "string"
      ? (JSON.parse(request.body.data) as unknown)
      : undefined
  if (
    !data ||
    typeof data !== "object" ||
    !("id" in data) ||
    typeof data.id !== "string"
  ) {
    throw new AuthError("Invalid WebAuthn Registration response")
  }

  // Get challenge from request cookies
  const { challenge: expectedChallenge, registerData: user } =
    await webauthnChallenge.use(options, request.cookies, resCookies)
  if (!user) {
    throw new AuthError(
      "Missing user registration data in WebAuthn challenge cookie"
    )
  }

  // Verify the response
  let verification: VerifiedRegistrationResponse
  try {
    const relayingParty = provider.getRelayingParty(options, request)
    verification = await provider.simpleWebAuthn.verifyRegistrationResponse({
      ...provider.verifyRegistrationOptions,
      expectedChallenge,
      response: data as RegistrationResponseJSON,
      expectedOrigin: relayingParty.origin,
      expectedRPID: relayingParty.id,
    })
  } catch (e: any) {
    throw new WebAuthnVerificationError(e)
  }

View on GitHub (pinned to a1a16a5a77)

Solutions

  1. Pass user data in the options when initiating registration so registerData is embedded in the challenge cookie
  2. Clear stale cookies and restart the registration flow in a single tab
  3. Upgrade/restart consistently so client and server use the same challenge cookie format
  4. Check middleware/proxy settings that may drop or truncate cookies

Example fix

// before
await WebAuthnBrowser.startRegistration({ challenge: c }) // no user
// after
await registrationFlow({ ..., user: { name: userName, email: userEmail } })
Defensive patterns

Strategy: validation

Validate before calling

const { registerData: user } = await webauthnChallenge.use(options, request.cookies, resCookies)
if (!user) {
  return new Response('Registration session expired, restart the flow', { status: 400 })
}

Try / catch

try {
  await verifyRegister(data)
} catch (e) {
  if (e instanceof AuthError && e.message.includes('Missing user registration data')) {
    // redirect the user to restart the registration flow
  }
}

Prevention

When it happens

Trigger: The registration flow's challenge cookie lacks the registerData payload — options.user was not supplied to startRegistration/registrationFlow, or the cookie was written by a different/older flow version.

Common situations: Calling the registration endpoint without passing user (name/email) in options; cookie serialization/deserialization mismatch after library upgrades; cookie truncated by size limits or middleware stripping it; multiple tabs overwriting each other's challenge cookies.

Related errors


AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28). Data as JSON: /api/errors/d4d6965d93dcd360. Report an issue: GitHub.