mastra-ai/mastra · error
Invalid or tampered state token
Error message
Invalid or tampered state token
What it means
After splitting the state token, verifyStateToken recomputes the HMAC-SHA256 signature of the payload with the server secret and compares it to the signature in the token using a timing-safe comparison. If they differ, the payload was modified, was signed with a different secret, or is not from this server — so it throws 'Invalid or tampered state token' to prevent CSRF and open-redirect via a forged redirectUri.
Source
Thrown at auth/auth0/src/index.ts:130
return `${payloadB64}.${signature}`;
}
/**
* Verify and decode a state token.
* Returns the original state and redirectUri if valid and not expired.
*/
function verifyStateToken(stateToken: string, secret: string): { originalState: string; redirectUri: string } {
const parts = stateToken.split('.');
if (parts.length !== 2) {
throw new Error('Invalid state token format');
}
const [payloadB64, signature] = parts as [string, string];
// Verify signature
const expectedSig = hmacSign(payloadB64, secret);
if (!timingSafeEqual(signature, expectedSig)) {
throw new Error('Invalid or tampered state token');
}
// Decode and check expiry
let payload: StatePayload;
try {
payload = JSON.parse(atob(payloadB64)) as StatePayload;
} catch {
throw new Error('Invalid state token payload');
}
if (payload.e < Date.now()) {
throw new Error('State token has expired');
}
return {
originalState: payload.s,
redirectUri: payload.r,
};View on GitHub (pinned to 75dd419e61)
Solutions
- Ensure the same signing secret is configured on both the login endpoint and the callback endpoint (same env var, same value) and was not rotated mid-flow.
- Confirm multi-instance/multi-region deployments share the secret via the same secret store.
- Restart the login flow — a mismatched or expired token can never be verified; the user must begin a new OAuth authorize redirect.
- If this fires unexpectedly in production, audit for token tampering (potential CSRF) and log the event server-side without trusting the payload.
- Do not weaken or bypass the timing-safe comparison; verify against the exact payload string received.
Example fix
// before
const token = verifyStateToken(state, process.env.AUTH0_SECRET ?? 'dev-secret');
// after
const secret = process.env.AUTH0_SECRET;
if (!secret) throw new Error('AUTH0_SECRET not configured');
const token = verifyStateToken(state, secret); Defensive patterns
Strategy: try-catch
Validate before calling
// No caller-side check can verify HMAC; instead ensure secret parity before the flow:
if (!process.env.AUTH0_SECRET) {
throw new Error('Refusing to run OAuth flow: AUTH0_SECRET is not set');
} Try / catch
try {
const { originalState, redirectUri } = verifyStateToken(state, secret);
} catch (err) {
if (err instanceof Error && err.message === 'Invalid or tampered state token') {
log.warn('OAuth state signature mismatch — possible CSRF or secret rotation', { hasState: !!state });
return new Response('Invalid OAuth state', { status: 400 });
}
throw err;
} Prevention
- Use one shared, persistent signing secret across all instances and environments; never fall back to defaults.
- Plan secret rotation to leave old tokens invalid — send users to a fresh login rather than failing mid-callback.
- Log signature mismatches server-side as potential CSRF signals.
- Never log or echo the token payload on failure (it is untrusted).
When it happens
Trigger: Calling verifyStateToken with a token whose signature part doesn't match hmacSign(payloadB64, secret): hand-edited payload, token generated with a different/rotated secret, or a token copied from another environment (staging token verified in production).
Common situations: SESSION/AUTH secret differs between environments or changed between the login redirect and callback (deploy, secret rotation, missing env var falling back to a default); multi-instance deployments without a shared secret; an attacker-supplied state in a CSRF attempt (this error is the protection working).
Related errors
- Invalid state token signature
- Invalid state token signature
- Invalid state token format
- Invalid state token payload
- Redirect URI is required for SSO. Set AUTH0_REDIRECT_URI or
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/556615bb6b7afcc5.
Report an issue: GitHub.