Users can't log in after deploy
appears when:first production sign-in after a Vercel deploy — works on localhost, 401 loop on yourapp.com.
Users can't log in after deploy
Login worked locally, fails the moment you ship. Four causes cover nearly every case: rejected session cookie, rotating NEXTAUTH_SECRET, Supabase Site URL stuck on localhost, or CORS blocking the auth endpoint.
Users can't log in after deploy because production enforces rules localhost ignores: cookies without Secure get dropped over HTTPS, NEXTAUTH_SECRET auto-rotates between Vercel lambdas, and Supabase Site URL still points at localhost. Open devtools → Application → Cookies, sign in, and watch the session cookie. The fix is usually one env var plus aligned cookie options — ships the same day.
Quick fix for users can't log in after deploy
01// Vercel Settings → Environment Variables (Production)02NEXTAUTH_SECRET=$(openssl rand -base64 32)03NEXTAUTH_URL=https://yourapp.com04 05// Supabase Dashboard → Authentication → URL Configuration06Site URL: https://yourapp.com07Redirect URLs: https://yourapp.com/**08 09// auth.config.ts — align cookie with production10export const config = {11 cookies: {12 sessionToken: {13 name: 'next-auth.session-token',14 options: {15 httpOnly: true,16 sameSite: 'lax',17 secure: true, // HTTPS only in prod18 path: '/',19 },20 },21 },22};Deeper fixes when the quick fix fails
01 · Users can't log in after deploy — fix
The default Supabase client stores sessions in localStorage, which server components cannot read. Every protected route bounces to /login because the server renders signed-out while the browser thinks the user is signed in. Replace the browser client with the @supabase/ssr helpers so the same cookie is readable on both sides.
01import { createServerClient } from '@supabase/ssr';02import { cookies } from 'next/headers';03 04export async function getSupabase() {05 const store = await cookies();06 return createServerClient(07 process.env.NEXT_PUBLIC_SUPABASE_URL!,08 process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,09 {10 cookies: {11 getAll: () => store.getAll(),12 setAll: (all) => all.forEach((c) => store.set(c)),13 },14 },15 );16}02 · Fix CORS on custom auth APIs
If the auth endpoint lives on a different origin (api.yourapp.com) the preflight must return 204 with Access-Control-Allow-Origin and Access-Control-Allow-Credentials: true, and the fetch must include credentials: 'include'. A missing header looks identical to an auth failure in Vercel logs.
01export async function OPTIONS() {02 return new Response(null, {03 status: 204,04 headers: {05 'Access-Control-Allow-Origin': 'https://yourapp.com',06 'Access-Control-Allow-Credentials': 'true',07 'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',08 'Access-Control-Allow-Headers': 'content-type,authorization',09 },10 });11}03 · Lock the cookie domain for apex + www
If you deploy to both yourapp.com and www.yourapp.com without a canonical redirect, a cookie scoped to one host is invisible on the other. Either force a canonical host in middleware, or set domain: '.yourapp.com' so the session is readable on every subdomain.
Why AI-built apps hit users can't log in after deploy
Lovable, Bolt, and Cursor all scaffold auth with the same optimistic defaults: no Secure cookie flag, no explicit NEXTAUTH_SECRET, Supabase Site URL pointed at whatever preview host the generator was using that week. The generator tests against localhost:3000, sees the login working, and marks the task complete. The whole class of rules that kicks in on HTTPS — browsers refusing SameSite=None without Secure, load balancers rotating lambdas, Safari ITP treating cross-site cookies as tracking — simply never runs in the builder's sandbox.
The most punishing variant is a silent NEXTAUTH_SECRET drift. Auth.js falls back to an auto-generated secret when the env var is unset, and that fallback is stable within a single Vercel lambda instance but changes across cold starts. A user signs in on instance A, gets a token signed with secret A, and on the next request the load balancer routes them to instance B, which has secret B, sees an invalid signature, and logs them out. From the user's point of view, "login works sometimes" — which is worse than outright failure because it looks flaky rather than broken.
Supabase adds its own layer. The default Supabase client stores the session in localStorage, but server components on Next.js 16 App Router only see cookies. If the founder has not wired up the @supabase/ssr helpers, the browser thinks the user is logged in while the server keeps rendering the signed-out state. Every request to a protected route bounces back to /login and the user lands in a redirect loop.
users can't log in after deploy by AI builder
How often each AI builder ships this error and the pattern that produces it.
| Builder | Frequency | Pattern |
|---|---|---|
| Lovable | Very high | Ships Supabase Site URL pointed at preview host; SSR cookie helpers not wired. |
| Bolt.new | High | Omits NEXTAUTH_SECRET from Vercel env; Auth.js falls back to per-instance secret. |
| v0 | High | Ships Auth.js with default cookie options and no Secure flag for production. |
| Cursor | Medium | Hard-codes cookie domain to www or apex, breaking the other host. |
| Replit | Medium | Preview replit.dev origin leaked into Supabase Site URL and Google OAuth redirects. |
| Claude Code | Low | Writes correct server client but forgets the matching middleware cookie pass-through. |
| Windsurf | Low | Produces SameSite=Strict for 'security' — blocks OAuth cross-site redirect. |
| Base44 | Medium | Session stored in localStorage only; App Router server can't read it. |
Related errors we fix
- Session expires immediately after loginread the fix →
- OAuth callback URL not working in productionread the fix →
- Google OAuth redirect_uri_mismatchread the fix →
- Password reset email not sendingread the fix →
- Env variables not loading on Vercelread the fix →
- App works locally but not in productionread the fix →
Stop users can't log in after deploy recurring in AI-built apps
- →Pin NEXTAUTH_SECRET once via openssl rand -base64 32 and never rotate it during a hotfix.
- →Add a CI check that greps the repo for http://localhost in Supabase or OAuth config.
- →Ship a post-deploy smoke test: incognito sign-in + refresh on production within 5 minutes of deploy.
- →Wire the @supabase/ssr helpers before writing a single protected route on App Router.
- →Test every release in Safari — ITP rules surface cookie problems Chrome forgives.
Still stuck with users can't log in after deploy?
Restore login today — we ship production auth fixes same-day.
- →Diagnosis covers cookies, CORS, Supabase, and NEXTAUTH_SECRET drift
- →Free 30-minute triage before any paid work
- →Written root-cause report you can hand to investors or the team
users can't log in after deploy questions
Why can users log in locally but not after I deploy?+
What is a NEXTAUTH_SECRET mismatch and how do I detect it?+
How do I fix the login cookie not being set in production?+
Why does Supabase auth fail after deploy even when env vars are right?+
How long does it take to fix users can't log in after deploy?+
Ship the fix. Keep the fix.
Emergency Triage restores service in 48 hours. Break the Fix Loop rebuilds CI so this error cannot ship again.
Hyder Shah leads Afterbuild Labs, shipping production rescues for apps built in Lovable, Bolt.new, Cursor, Replit, v0, and Base44. our rescue methodology.
users can't log in after deploy experts
If this problem keeps coming back, you probably need ongoing expertise in the underlying stack.