nextauthjs/next-auth · error · AuthError

WebAuthn user not found in database: ${JSON.stringify({crede

Error message

WebAuthn user not found in database: ${JSON.stringify({credentialID, providerAccountId: authenticator.providerAccountId, userID: account.userId})}

What it means

The account was found, but adapter.getUser(account.userId) returned no user. Since the account row points to a non-existent user, authentication cannot complete and this AuthError is thrown including credentialID, providerAccountId, and the missing userID.

Source

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

  }

  // Get the account and user
  const account = await adapter.getAccount(
    authenticator.providerAccountId,
    provider.id
  )
  if (!account) {
    throw new AuthError(
      `WebAuthn account not found in database: ${JSON.stringify({
        credentialID,
        providerAccountId: authenticator.providerAccountId,
      })}`
    )
  }

  const user = await adapter.getUser(account.userId)
  if (!user) {
    throw new AuthError(
      `WebAuthn user not found in database: ${JSON.stringify({
        credentialID,
        providerAccountId: authenticator.providerAccountId,
        userID: account.userId,
      })}`
    )
  }

  return {
    account,
    user,
  }
}

export async function verifyRegister(
  options: InternalOptions<WebAuthnProviderType>,
  request: RequestInternal,
  resCookies: Cookie[]

View on GitHub (pinned to a1a16a5a77)

Solutions

  1. Add ON DELETE CASCADE (or cleanup logic) so deleting a user removes its accounts and authenticators
  2. Clean up orphaned Account/Authenticator rows referencing missing users
  3. Verify adapter.getUser is querying the correct users table/ID type
  4. Re-register the passkey to rebuild consistent user/account/authenticator records

Example fix

// before
// manual delete left orphan rows
await db.user.delete({ where: { id } })
// after
await db.user.delete({ where: { id } }) // with cascade:
// schema: Account.userId references User.id onDelete: Cascade
Defensive patterns

Strategy: validation

Validate before calling

const account = await adapter.getAccount(authenticator.providerAccountId, provider.id)
if (account) {
  const user = await adapter.getUser(account.userId)
  if (!user) {
    // repair or delete the dangling account before authenticating
  }
}

Try / catch

try {
  await verifyAuthenticate(data)
} catch (e) {
  if (e instanceof AuthError && e.message.includes('user not found')) {
    // remove orphaned account+authenticator rows, re-register
  }
}

Prevention

When it happens

Trigger: A dangling Account row whose userId references a deleted or never-created User record, encountered during verifyAuthenticate.

Common situations: Users hard-deleted without cascading account/authenticator rows; manual DB cleanup; adapters lacking FK constraints allowing orphaned rows; partial backups/restores.

Understand the failure class

Related errors


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