Authentication
Debugging “signed in but still 401” in Next.js server code
Why your session works in the browser but not in route handlers or server components — and how to fix it.
5 min read
The symptom
The client shows you as signed in, but a route handler or server component sees no user, or the session works until the access token expires and then fails.
Check that cookies reach the server
- Open your browser dev tools → Application → Cookies and confirm the auth cookies exist for your domain.
- In the failing request (Network tab), check the Cookie request header includes them.
- If you call your API from the server, forward cookies explicitly — server-side fetch doesn't send the browser's cookies automatically.
Create the server client per request
Server auth clients must read cookies from the current request and be able to write refreshed tokens back. Create the client inside the handler, not once at module scope.
export async function GET() {
const supabase = await createClient(); // reads this request's cookies
const { data: { user } } = await supabase.auth.getUser();
if (!user) return new Response("Unauthorized", { status: 401 });
// ...
}Refresh tokens somewhere that can set cookies
Server components can read cookies but can't set them. Make sure token refresh happens in a route handler, server action or request proxy so the renewed cookies are actually saved.
Use getUser() for authorization
Decisions about access should rely on a verified user (for example auth.getUser()), not on unverified session data decoded from a cookie.
Still stuck? Ask the community or request a human review.