nextauthjs/next-auth · error
Authenticator not created
Error message
Authenticator not created
What it means
createAuthenticator() persists a WebAuthn/passkey authenticator. If the SurrealDB create throws or returns an empty array, the adapter throws 'Authenticator not created', discarding the root cause in an empty catch.
Source
Thrown at packages/adapter-surrealdb/src/index.ts:503
)
if (accountsDoc.length) {
return docToAccount(accountsDoc[0])
}
} catch {}
return null
},
async createAuthenticator(authenticator: AdapterAuthenticator) {
try {
const surreal = await client
const authenticatorDoc = await surreal.create<
AuthenticatorDoc,
Omit<AuthenticatorDoc, "id">
>("authenticator", authenticatorToDoc(authenticator))
if (authenticatorDoc.length) {
return docToAuthenticator(authenticatorDoc[0])
}
} catch {}
throw new Error("Authenticator not created")
},
async getAuthenticator(credentialId: AdapterAuthenticator["credentialID"]) {
const surreal = await client
try {
const [authenticatorDoc] = await surreal.query<[AuthenticatorDoc[]]>(
`SELECT * FROM authenticator WHERE credentialID = $cid LIMIT 1`,
{
cid: credentialId,
}
)
if (authenticatorDoc.length) {
return docToAuthenticator(authenticatorDoc[0])
}
} catch {}
return null
},
async listAuthenticatorsByUserId(userId: AdapterAuthenticator["userId"]) {
const surreal = await clientView on GitHub (pinned to a1a16a5a77)
Solutions
- Verify SurrealDB is reachable and the `authenticator` table exists and is writable
- Check permissions allow CREATE on the authenticator table for the adapter user
- Ensure the WebAuthn credential payload (credentialID, publicKey, counter) is complete before the call
- Add temporary logging inside the try to expose the underlying error
Defensive patterns
Strategy: validation
Validate before calling
if (!authenticator?.credentialID || !authenticator?.credentialPublicKey) {
throw new Error('Authenticator payload missing credentialID/publicKey')
}
await adapter.createAuthenticator(authenticator) Type guard
function isValidAuthenticator(a: AdapterAuthenticator): boolean {
return typeof a.credentialID === 'string' && a.credentialID.length > 0 &&
a.credentialPublicKey != null && typeof a.userId === 'string'
} Try / catch
try {
return await adapter.createAuthenticator(authenticator)
} catch (e) {
if (e.message === 'Authenticator not created') {
console.error('WebAuthn authenticator insert failed — check SurrealDB', e)
}
throw e
} Prevention
- Validate WebAuthn registration payload before persisting
- Grant CREATE on the authenticator table to the adapter role
- Watch for duplicate credentialID inserts
When it happens
Trigger: surreal.create('authenticator', ...) fails (connectivity, permissions, schema) or yields zero rows; authenticatorToDoc produced invalid fields (e.g. credentialID/credentialPublicKey malformed).
Common situations: Passkey registration failing because the authenticator table lacks CREATE permission; SurrealDB misconfigured namespace/database; duplicate credentialID being inserted.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Verification Token not found
- Unable to update authenticator with credential ${credentialI
- User id is required
- User not updated
- Account not created
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/a3d5bc2f74314a76.
Report an issue: GitHub.