Auth0 error
The state parameter is invalid. (nextjs-auth0 on Vercel)
"The state parameter is invalid." is the plain-text 500 that @auth0/nextjs-auth0 v4 returns from /auth/callback when it finds no transaction cookie for the state in the URL. The SDK sets a cookie named __txn_ plus the state when /auth/login runs and reads it back on the callback, and the browser sends it only to the host that set it. On Vercel it appears when login starts on one host and the callback lands on another, for example a static APP_BASE_URL set to the production domain while you sign in on a preview, or when AUTH0_SECRET differs between the two requests. It also appears when the cookie has expired. "The state parameter is missing." means the callback URL had no state. Reproduced with @auth0/nextjs-auth0 4.33.0 on 2026-10-31.
Why does a preview deployment send the callback to production?
With a static APP_BASE_URL the SDK builds the redirect_uri from that value, whatever host you opened. In a run of @auth0/nextjs-auth0 4.33.0 on 2026-10-31, with a fake tenant and a mocked discovery response, APP_BASE_URL=https://app.example.com and a login request to https://app-git-feature-team.vercel.app/auth/login gave redirect_uri=https://app.example.com/auth/callback, and the __txn_ cookie came back with no Domain attribute, so it belongs to the preview host only. When Auth0 sends the browser to app.example.com, that host has no such cookie. The nextjs-auth0 docs warn about this case: a static APP_BASE_URL forces every redirect_uri to one origin, which causes state parameter mismatches when the app is served through preview deployments.
Login: https://app-git-feature-team.vercel.app/auth/login
redirect_uri = https://app.example.com/auth/callback
Set-Cookie: __txn_<state>=<value>; Path=/; Max-Age=3600; HttpOnly; SameSite=lax
Callback: https://app.example.com/auth/callback?code=x&state=<state>
no __txn_<state> cookie on this host
HTTP 500 The state parameter is invalid.What else makes the state invalid or missing?
The SDK encrypts the transaction cookie with AUTH0_SECRET. In the same mocked run, a callback that carried a valid cookie but reached a client built with a different secret also answered "The state parameter is invalid.", so a secret that differs between the login request and the callback fails the same way. The cookie lives for 3600 seconds by default (transactionCookie.maxAge), so a login tab left open for more than an hour fails too. A callback URL opened by hand, or in another browser, has no state cookie either. A callback without a state query parameter gives "The state parameter is missing."
I see "Missing state cookie from login request" instead
That text is from nextjs-auth0 v3 ("Callback handler failed. CAUSE: Missing state cookie from login request"). In an Auth0 Support article for version 3.5.0 the cause was a custom flow that built the /authorize URL by hand and skipped the SDK's login handler, which is the code that sets the state cookie. Start sign-in from the SDK's login route (/api/auth/login in v3, /auth/login in v4) as a normal browser navigation.
If Auth0 itself shows an error before the app is reached, that is a different failure: Callback URL mismatch. The provided redirect_uri is not in the list of allowed callback URLs..
Checklist
How to fix it, then check the fix
- 01Compare two hosts: the one in the address bar when you pressed login, and the host in the redirect_uri of the /authorize URL. If they differ, APP_BASE_URL is the cause.
- 02Set APP_BASE_URL per environment in Vercel. Production gets its custom domain. On Preview, leave it unset so the host is inferred, or list every origin that environment serves, comma-separated:
vercel env add APP_BASE_URL production - 03Register the resulting /auth/callback URL of each origin in Allowed Callback URLs in the Auth0 Dashboard, because Auth0 rejects any redirect_uri that is not listed.
- 04Use the same AUTH0_SECRET for the login request and the callback, which means one value for the environment and no change between deployments in the middle of a sign-in.
- 05Start sign-in from the /auth/login route, not from a hand-built /authorize link, and finish within the hour.
- 06Redeploy, since Vercel applies changed variables only to new deployments. Then sign in from /auth/login on the preview: you should land back on your app with a session, not on a 500.
Related
Related guides
Sources
Official docs behind this checklist
- nextjs-auth0, errors/oauth-errors.ts (MissingStateError, InvalidStateError)
- nextjs-auth0, server/auth-client.ts (handleCallback)
- nextjs-auth0, server/transaction-store.ts
- nextjs-auth0, EXAMPLES.md (Dynamic Application Base URLs, Transaction Cookie Configuration)
- nextjs-auth0, README (dynamic base URLs)
- Auth0 Support, Missing state cookie from login request
- Vercel, Environment variables
- Vercel, Environments (preview URLs)
More Next.js errors · More Auth0 errors
Browse all launch guides · Read resources · How to make and check your next change
FAQ
FAQ for builders before launch
Why does it only fail on preview deployments?
Each preview has its own host, and the transaction cookie is bound to the host that set it. A static APP_BASE_URL sends the callback to the production host, which never received the cookie.
Is the Vercel proxy changing my host?
The SDK infers the base URL from the x-forwarded-proto and x-forwarded-host headers when APP_BASE_URL is not set. The nextjs-auth0 docs say Vercel deployments are not affected by header spoofing because Vercel strips and validates these headers.
Is this the same as the Callback URL mismatch page from Auth0?
No. Callback URL mismatch is shown by Auth0 before your app is reached, because the redirect_uri is not in Allowed Callback URLs. The state error comes from your own /auth/callback route, after Auth0 has accepted the redirect.