nextauthjs/next-auth · error · AdapterError

Failed to update authenticator counter. This may cause futur

Error message

Failed to update authenticator counter. This may cause future authentication attempts to fail. ${JSON.stringify({credentialID, oldCounter: authenticator.counter, newCounter: authenticationInfo.newCounter})}

What it means

The credential verification succeeded, but updating the authenticator's signature counter via adapter.updateAuthenticatorCounter failed. The library escalates it to an AdapterError with details because a stale counter can cause future assertions to be rejected as cloned authenticators.

Source

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

  const { verified, authenticationInfo } = verification

  // Make sure the response was verified
  if (!verified) {
    throw new WebAuthnVerificationError(
      "WebAuthn authentication response could not be verified"
    )
  }

  // Update authenticator counter
  try {
    const { newCounter } = authenticationInfo
    await adapter.updateAuthenticatorCounter(
      authenticator.credentialID,
      newCounter
    )
  } catch (e: any) {
    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(

View on GitHub (pinned to a1a16a5a77)

Solutions

  1. Check database connectivity and adapter error logs for the root cause
  2. Implement updateAuthenticatorCounter in your custom adapter if missing
  3. Verify the Authenticator table still has a counter column in your schema
  4. Re-run authentication once the adapter write path is healthy

Example fix

// before
// adapter missing updateAuthenticatorCounter -> AdapterError
// after
async updateAuthenticatorCounter(credentialID, counter) {
  await db.authenticator.update({ where: { credentialID }, data: { counter } })
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (typeof adapter.updateAuthenticatorCounter !== 'function') {
  throw new Error('Adapter must implement updateAuthenticatorCounter')
}

Try / catch

try {
  await verifyAuthenticate(data)
} catch (e) {
  if (e instanceof AdapterError && e.message.includes('authenticator counter')) {
    logger.error(e.message) // auth succeeded but counter stale; alert ops
  } else { throw e }
}

Prevention

When it happens

Trigger: updateAuthenticatorCounter throws inside verifyAuthenticate — adapter not connected, DB write error, or a custom adapter that doesn't implement updateAuthenticatorCounter.

Common situations: Database connection pool exhausted or down at write time; custom adapter missing the updateAuthenticatorCounter method; schema migration removed the counter column; permissions preventing updates.

Understand the failure class

Related errors


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