nextauthjs/next-auth · error
Verification Token not created
Error message
Verification Token not created
What it means
createVerificationToken() stores an email verification / magic-link token. If the SurrealDB create fails or returns an empty result, the adapter throws 'Verification Token not created' after swallowing the underlying error.
Source
Thrown at packages/adapter-surrealdb/src/index.ts:442
async createVerificationToken(verificationToken: VerificationToken) {
try {
const surreal = await client
const doc = verificationTokenToDoc(verificationToken)
const verificationTokenDocs = await surreal.create<
VerificationTokenDoc,
Omit<VerificationTokenDoc, "id">
>("verification_token", doc)
if (verificationTokenDocs.length) {
const verificationTokenDoc: Partial<VerificationTokenDoc> =
verificationTokenDocs[0]
if (verificationTokenDoc.id) delete verificationTokenDoc.id
return docToVerificationToken(
verificationTokenDoc as VerificationTokenDoc
)
}
} catch {}
throw new Error("Verification Token not created")
},
async useVerificationToken({
identifier,
token,
}: {
identifier: string
token: string
}) {
const surreal = await client
try {
const [tokens] = await surreal.query<[VerificationTokenDoc[]]>(
`SELECT * FROM verification_token WHERE identifier = $identifier AND token = $vt LIMIT 1`,
{ identifier, vt: token }
)
if (tokens.length && tokens.at(0)) {
const vt = tokens[0]
if (vt) {
await surreal.delete(vt.id)View on GitHub (pinned to a1a16a5a77)
Solutions
- Confirm the verification token table exists and the adapter credentials can create rows in it
- Verify SurrealDB connection env vars (URL, namespace, database, auth) are correct
- Log inside the try to reveal the suppressed root error
- Check that identifier/token/expires values passed by the core are valid (non-null, correct types)
Defensive patterns
Strategy: try-catch
Validate before calling
if (!identifier || !token || !(expires instanceof Date)) {
throw new Error('Invalid verification token payload')
}
await adapter.createVerificationToken({ identifier, token, expires }) Try / catch
try {
return await adapter.createVerificationToken(params)
} catch (e) {
if (e.message === 'Verification Token not created') {
console.error('Token creation failed — check SurrealDB table/permissions', e)
}
throw e
} Prevention
- Ensure the verification_token table exists before first sign-in
- Keep SurrealDB auth env vars consistent across environments
- Log adapter errors; the empty catch hides root causes
When it happens
Trigger: surreal.create('verification_token', ...) throws (connection/permission/schema) or returns an empty array; malformed token payload fields (identifier/token/expires) after userToDoc-style conversion.
Common situations: Email magic-link or email-verification flows failing at sign-in; SurrealDB table missing because migrations were never run; adapter lacking CREATE permission on the verification token table.
Related errors
- Verification Token not used
- User id is required
- User not updated
- Account not created
- Authenticator not created
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/1aabf385efdc8d15.
Report an issue: GitHub.