nextauthjs/next-auth · error · AuthError
WebAuthn account not found in database: ${JSON.stringify({cr
Error message
WebAuthn account not found in database: ${JSON.stringify({credentialID, providerAccountId: authenticator.providerAccountId})} What it means
After finding the authenticator, verifyAuthenticate fetches the linked account via adapter.getAccount(authenticator.providerAccountId, provider.id). If no account row exists for that provider account, authentication cannot resolve to a user, so this AuthError is thrown with the credentialID and providerAccountId for debugging.
Source
Thrown at packages/core/src/lib/utils/webauthn-utils.ts:295
throw new AdapterError(
`Failed to update authenticator counter. This may cause future authentication attempts to fail. ${JSON.stringify(
{
credentialID,
oldCounter: authenticator.counter,
newCounter: authenticationInfo.newCounter,
}
)}`,
e
)
}
// 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,
})}`
)
}
View on GitHub (pinned to a1a16a5a77)
Solutions
- Check the Account table for the providerAccountId and provider.id pair
- Ensure WebAuthn provider id matches what was used at registration
- Fix or re-implement adapter.getAccount so it matches the account by providerAccountId and provider
- Re-link the account or re-register the passkey if data is inconsistent
Example fix
// before
provider: { id: "passkey", ... } // registered under "webauthn"
// after
provider: { id: "webauthn", ... } // match the original provider id Defensive patterns
Strategy: validation
Validate before calling
const account = await adapter.getAccount(authenticator.providerAccountId, provider.id)
if (!account) {
// unlink the stale authenticator or re-link the account before authenticating
} Try / catch
try {
await verifyAuthenticate(data)
} catch (e) {
if (e instanceof AuthError && e.message.includes('account not found')) {
// clean up orphaned authenticator, prompt re-registration
}
} Prevention
- Cascade account deletions to authenticators
- Never change the WebAuthn provider id after go-live
- Back up and restore the full relational graph, not partial tables
- Test adapter.getAccount against your actual schema
When it happens
Trigger: The authenticator exists but its providerAccountId no longer maps to an Account row — account deleted, provider id changed, or adapter returning null for a valid lookup due to schema/encoding mismatch.
Common situations: Users deleting their OAuth/account link while the passkey remains; custom adapters that don't implement getAccount properly; provider id changed in AuthConfig (e.g. from 'webauthn' to a custom id); database restored partially from backup.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- WebAuthn authenticator not found in database: ${JSON.stringi
- Failed to update authenticator counter. This may cause futur
- An adapter is required for the WebAuthn provider
- WebAuthn provider requires a database adapter to be configur
- Unable to update authenticator with credential ${credentialI
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/96016577a2056bc4.
Report an issue: GitHub.