nextauthjs/next-auth · error · MissingCSRF
CSRF token was missing during an action ${action}
Error message
CSRF token was missing during an action ${action} What it means
Auth.js throws MissingCSRF when a state-changing auth action (signin, signout, callback) arrives without the CSRF token cookie that was set when the session/page was rendered. The library requires the csrfToken cookie value to match the csrfToken POSTed in the form body to prevent cross-site request forgery against the auth endpoints.
Source
Thrown at packages/core/src/lib/actions/callback/oauth/csrf-token.ts:59
// If this is a POST request and the CSRF Token in the POST request matches
// the cookie we have already verified is the one we have set, then the token is verified!
const csrfTokenVerified = isPost && csrfToken === bodyValue
return { csrfTokenVerified, csrfToken }
}
}
// New CSRF token
const csrfToken = randomString(32)
const csrfTokenHash = await createHash(`${csrfToken}${options.secret}`)
const cookie = `${csrfToken}|${csrfTokenHash}`
return { cookie, csrfToken }
}
export function validateCSRF(action: AuthAction, verified?: boolean) {
if (verified) return
throw new MissingCSRF(`CSRF token was missing during an action ${action}`)
}
View on GitHub (pinned to a1a16a5a77)
Solutions
- Fetch GET /api/auth/csrf first, then POST the csrfToken value in the request body while sending cookies (credentials: 'include' in browsers)
- Verify cookies are enabled and not blocked: check Secure/SameSite attributes match HTTPS deployment and that the request is same-site, or configure cookies.cookies.sessionToken/partner options in AuthOptions
- If using a custom login form, include the csrfToken as a hidden field (NextAuth useSession/csrf helpers) in the POSTed form data
- Check reverse proxy/CDN configuration (e.g. Cloudflare, Vercel rewrites) is not stripping the Set-Cookie header that delivers the CSRF cookie
- Clear stale cookies and retry: an expired/rotated CSRF cookie can mismatch after secret changes; ensure NEXTAUTH_SECRET/AUTH_SECRET is stable across instances
Example fix
// before
csrfToken: "useSecureCookies" ? undefined : null,
// after
const res = await fetch(`${baseUrl}/api/auth/csrf`, { credentials: 'include' });
const { csrfToken } = await res.json();
await fetch(`${baseUrl}/api/auth/signin/credentials`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
credentials: 'include',
body: new URLSearchParams({ csrfToken, username, password }),
}); Defensive patterns
Strategy: try-catch
Validate before calling
const r = await fetch(`${baseUrl}/api/auth/csrf`, { credentials: 'include' });
const { csrfToken } = await r.json();
if (!csrfToken) throw new Error('No CSRF token available'); Type guard
function hasCsrf(x: unknown): x is { csrfToken: string } {
return typeof x === 'object' && x !== null && typeof (x as any).csrfToken === 'string' && (x as any).csrfToken.length > 0;
} Try / catch
try {
await signIn(provider, options, formData);
} catch (e) {
if (e instanceof MissingCSRF || /CSRF token was missing/.test(String(e))) {
// refresh CSRF token via GET /api/auth/csrf and retry once with credentials: 'include'
}
} Prevention
- Always fetch /api/auth/csrf before POSTing to any auth action endpoint
- Send cookies with every auth request (credentials: 'include')
- Keep AUTH_SECRET stable so CSRF cookies remain valid across deploys
- Check SameSite/Secure cookie attributes match your deployment (HTTPS vs localhost)
- Verify proxies/CDNs do not strip Set-Cookie headers
When it happens
Trigger: POSTing to /api/auth/callback/*, /api/auth/signout, or /api/auth/signin/* without the authjs.csrf-token (next-auth.csrf-token) cookie, or with a body/form value that does not include the csrfToken returned by GET /api/auth/csrf.
Common situations: Calling auth endpoints with fetch/axios or curl without first fetching /api/auth/csrf and sending credentials: 'include'; browser blocking cookies (SameSite/Secure/HTTPS mismatch, cross-subdomain requests); custom sign-in pages that forget the hidden csrfToken input; server-side redirects that drop cookies; reverse proxies stripping Set-Cookie headers.
Related errors
- ${name} cookie was missing
- csrf-disabled
- Invalid cookie
- ${name} cookie was created for a different provider than the
- ${name} value could not be parsed
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/759ce7bfc47e8c21.
Report an issue: GitHub.