Intermittent Error: `Authentication flow: State mismatch`
Hello all -- I am working on a project, and using Kinde for auth (which I quite love).
For this current project that I am working on, I've been intermittently getting this error as soon as I authenticate (with credentials).
{"error":"Authentication flow: State mismatch. Received: <some-string> | Expected: <some-other-string>"}
This error is shown on the URL "<mydomain>/api/auth/kinde_callback".
Stack:
Using Nextjs 15+, React 19+, kinde-oss/kinde-auth-nextjs ^2.8.0, deployed on Vercel.
I've been testing using the same browser, and the same account. The authentication works some of the times, but gives this error the other times.
I have verified that the following env variables are set on Vercel, and the domain is consistent:
Is this a known issues? Any guidance around how to debug? Happy to provide more details (domain, account etc.) in DM.
TY!5 Replies
Hi there,
Thanks for reaching out.
This is a known state mismatch error that occurs when the
state
cookie set at the start of the auth flow doesn't match what's received back from Kinde
(https://docs.kinde.com/developer-tools/sdks/backend/nextjs-sdk/#state-not-found-error). The error typically happens when you start the auth flow from one domain but get redirected to a different domain after authentication.
For your Vercel deployment, this is commonly caused by environment variable mismatches between your preview domains and production domains. Here's how to fix it:
Solution
1. Dynamically set environment variables for Vercel preview domains by adding this to your next.config.js
:
const nextConfig = {
env: {
KINDE_SITE_URL: process.env.KINDE_SITE_URL ?? https://${process.env.VERCEL_URL}
,
KINDE_POST_LOGOUT_REDIRECT_URL:
process.env.KINDE_POST_LOGOUT_REDIRECT_URL ?? https://${process.env.VERCEL_URL}
,
KINDE_POST_LOGIN_REDIRECT_URL:
process.env.KINDE_POST_LOGIN_REDIRECT_URL ?? https://${process.env.VERCEL_URL}/dashboard
}
};
module.exports = nextConfig;
2. Verify domain consistency - confirm that the domain you start the auth flow from matches the domain you're redirected to after authentication.
3. Check your callback URLs in Kinde match your KINDE_POST_LOGIN_REDIRECT_URL
environment variable.
Why This Happens
The state mismatch occurs because when you start the auth flow, a state
cookie is set which needs to be checked when you return to your app. If you start the flow on one domain (like a Vercel preview domain) but your environment variables redirect you to a different domain, the state
cookie won't be found, causing the security check to fail.
Since your KINDE_POST_LOGIN_REDIRECT_URL
environment variable is likely static across all deployments, you might be getting redirected to your main domain instead of staying on the preview domain where the auth flow started.
The dynamic configuration above ensures Vercel uses its generated preview URLs to populate the Kinde variables correctly
(https://docs.kinde.com/developer-tools/sdks/backend/nextjs-sdk/#working-with-preview-urls).
Please let me know if you have any more questions about this.Thanks Patrick for the detailed response.
The intriguing part is that I am not using Vercel's preview link/URLs at all. I only use my custom domain.
1. I navigate to my custom domain
https://blah.page
2. I click on the SIgnIn button, which takes me to: https://auth.blah.page/auth/...
(Yes, I have setup a custom domain on Kinde)
3. I login using credentials
4.1. Sometimes, I am successfully redirected to my login redirect URL: https://blah.page/me/resume/core
4.2. Other times, I get the provided error (Authentication flow: State mismatch.
) at URL https://blah.page/api/auth/kinde_callback?...
In vercel, my env variable KINDE_POST_LOGIN_REDIRECT_URL
is set to https://blah.page/me/resume/core
.
Note: In this message, I have replaced my domain with blah
, but kept other parts of the URL.
As suggested, I will try the suggested solution of dynamically setting the env variables using next.config.js, but I fail to understand why the issue would happen 1) intermittently & 2) on my custom domain.Your intermittent state mismatch error with custom domains is indeed puzzling since you're using consistent domains throughout the flow. Based on the Next.js SDK documentation and community reports, here are the most likely causes and solutions:
Potential Causes for Intermittent State Mismatch
1. Cookie Storage Issues
The
state
parameter is stored in cookies during the auth flow. On custom domains, cookie handling can be affected by:
- Browser cookie policies
- Subdomain configurations
- Cookie domain settings
2. Multiple Browser Tabs/Sessions
If you have multiple tabs open or overlapping auth sessions, the state cookies can get overwritten, causing intermittent failures.
3. Custom Domain Token Interchangeability
The documentation notes that tokens from custom domains and Kinde subdomains are not interchangeable. If there's any mixing of endpoints, this could cause state mismatches.
Debugging Steps
1. Check Cookie Domain Configuration
Since you're using a custom domain, verify your KINDE_COOKIE_DOMAIN
setting. For custom domains, this should typically be set to your root domain.
2. Use the Health Check Endpoint
Check your configuration using the health endpoint: https://blah.page/api/auth/health
. This will show you exactly what configuration values are being used.
3. Browser Developer Tools
Monitor the Network tab during auth flow to see:
- Which cookies are being set during login initiation
- Whether those same cookies are present during the callback
- Any cookie domain mismatches
4. Single Tab Testing
Test with only one browser tab open to eliminate session overlap issues.
Recommended Solutions
1. Explicit Cookie Domain Setting
Add this to your environment variables:
KINDE_COOKIE_DOMAIN=.blah.page
2. Enhanced Next.js Configuration
Even with custom domains, the dynamic configuration can help with consistency:
const nextConfig = {
env: {
KINDE_SITE_URL: process.env.KINDE_SITE_URL ?? 'https://blah.page',
KINDE_POST_LOGIN_REDIRECT_URL: process.env.KINDE_POST_LOGIN_REDIRECT_URL ?? 'https://blah.page/me/resume/core',
KINDE_POST_LOGOUT_REDIRECT_URL: process.env.KINDE_POST_LOGOUT_REDIRECT_URL ?? 'https://blah.page'
}
};
3. Use Kinde Link Components
Instead of regular links, use Kinde's LoginLink
component which handles state management more reliably:
import { LoginLink } from "@kinde-oss/kinde-auth-nextjs/components";
<LoginLink>Sign In</LoginLink>
The intermittent nature suggests a race condition or cookie handling issue rather than a configuration problem. The custom domain setup should work consistently once the cookie domain is properly configured.For those following this issue:
My issue got resolved after I made sure that I use Kinde's official Nextjs components (
LoginLink
, LogoutLink
, RegisterLink
). Initially, I was simply using custom components that would manually redirect to my auth endpoints (e.g. to .../api/auth/login
). That wasn't enough.
Switching to standard components solved this issue.I am happy to hear your issue has been resolved now. And thanks for providing the details.
Please let me know if there's anything else that I can assist with.