How to fix session_not_found: User session not found in Supabase
The "session_not_found" error occurs when Supabase Auth detects that the session ID in your JWT token no longer exists in the auth.sessions table. This typically happens due to session expiration, token refresh failures, or URL mismatches between your Supabase configuration and frontend application.
Quick fix
Fixes session_not_found
npm install @supabase/supabase-js@latest
npm install @supabase/ssr@latest- Upgrade Supabase client libraries to the latest version
- Verify Supabase site URL matches your frontend URL
- Use auth.getUser() instead of auth.getSession() for server-side verification
- Handle session errors with proper retry and logout logic
npm install @supabase/supabase-js@latestnpm install @supabase/ssr@latestsession_not_found: User session not found
What this error means
When you use Supabase authentication, the system creates a session and stores it in the auth.sessions table with a unique session ID. The JWT token that your client receives contains a claim referencing this session ID. The "session_not_found" error is returned when you attempt to use an access token, but the session ID embedded in that token is no longer valid or has been deleted from the database. This error specifically means: "Session from session_id claim in JWT does not exist." It can occur on the client side (when calling auth.getSession()) or on the server side (when calling auth.getUser() in API routes or middleware). The error can leave users unable to perform authenticated actions or even log themselves out.
Typical symptoms
- Getting 'session_not_found' error when calling auth.getUser() or auth.getSession()
- Users unable to make authenticated API requests after inactivity
- Login appears successful but subsequent requests fail with session errors
- signOut() method fails with the same session_not_found error
- AuthSessionMissing error when calling supabase.auth methods on server-side code
- Mixed localhost/127.0.0.1 URLs causing session validation to fail
Common causes
- User session has expired due to inactivity or token expiration time passing
- Session refresh mechanism failed due to network issues or service outages
- Mismatch between Supabase site URL (e.g., 127.0.0.1) and frontend URL (e.g., localhost) causing session validation to fail
- JWT access token expiration time too short, preventing ahead-of-time refresh
- Session was manually deleted from the auth.sessions table
- Upgrading Supabase client libraries without proper session recovery logic
- Server-side code not properly passing cookies/headers to Supabase client
- Multiple tabs open with stale sessions that get invalidated
How to fix "session_not_found: User session not found"
Update your Supabase JavaScript and SSR packages to the latest versions. Several fixes have been released to handle session_not_found errors:
npm install @supabase/supabase-js@latest
npm install @supabase/ssr@latestCheck your package.json to ensure you're running:
- @supabase/supabase-js v2.39.0 or later
- @supabase/ssr v0.0.10 or later
Older versions had session refresh bugs that could leave you in a stuck state.
A common cause is setting the Supabase site URL to 127.0.0.1 but accessing your frontend via localhost (or vice versa). These are treated as different origins and cause session validation to fail.
1. Go to your Supabase dashboard
2. Navigate to Project Settings > API
3. Check "Site URL" - it should match exactly how you access your frontend
For local development, use consistent URLs:
# Use localhost consistently:
Site URL: http://localhost:3000
# OR use 127.0.0.1 consistently:
Site URL: http://127.0.0.1:30004. Restart your development server after changing the site URL
5. Clear browser cookies for localhost and 127.0.0.1 to force fresh login
On the server side (API routes, middleware), always use auth.getUser() instead of auth.getSession(). The getUser() method makes a request to verify the session server-side, while getSession() just reads local data that could be tampered with.
For Next.js with SSR:
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';
export async function GET(request: Request) {
const cookieStore = await cookies();
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll();
},
},
}
);
const { data: { user }, error } = await supabase.auth.getUser();
if (error || !user) {
return new Response(JSON.stringify({ error: 'Unauthorized' }), {
status: 401,
headers: { 'Content-Type': 'application/json' },
});
}
return new Response(JSON.stringify({ user }));
}getUser() always makes a fresh request to verify the session exists, preventing stale session errors.
Wrap authentication calls in error handling that gracefully catches session_not_found and forces a logout:
async function callAuthenticatedEndpoint() {
try {
const { data: { user }, error } = await supabase.auth.getUser();
if (error?.message.includes('session_not_found')) {
console.warn('Session expired, signing out...');
await supabase.auth.signOut();
window.location.href = '/login';
return;
}
if (error) throw error;
return user;
} catch (error) {
console.error('Auth error:', error);
// Force sign out on any auth error
try {
await supabase.auth.signOut();
} catch (signoutError) {
// Ignore errors during logout - just clear locally
localStorage.removeItem('supabase.auth.token');
}
window.location.href = '/login';
}
}This prevents users from getting stuck in a failed state - they're automatically logged out and redirected to login.
Short JWT expiration times can cause clock skew issues where the token expires before the refresh mechanism can kick in. Increase the expiration time in your Supabase dashboard:
1. Go to Supabase Dashboard > Project Settings > Auth
2. Scroll to JWT Settings
3. Set "JWT expiry limit" (in seconds):
- Minimum: 3600 (1 hour)
- Recommended: 86400 (24 hours) or more for better UX
- Access tokens: Leave at 3600-7200 (1-2 hours)
Access token (JWT) expiry limit: 3600 seconds (1 hour)
Refresh token expiry limit: 604800 seconds (7 days)Supabase client libraries automatically attempt to refresh sessions before expiry, so longer expiration times give more buffer. The refresh token can be long-lived since it's used server-to-server.
If you're experiencing session_not_found during password recovery specifically, there's a known issue with the standard @supabase/ssr that's fixed in the patched version:
npm install @supabase/ssr@patchedThis version fixes issues where the session gets invalidated during the password reset callback flow. After updating, test password recovery end-to-end to ensure the session persists correctly.
Instead of manually checking sessions, let Supabase automatically manage session state with the onAuthStateChange listener:
import { useEffect, useState } from 'react';
export function useCurrentUser() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Listen for auth state changes
const { data: { subscription } } = supabase.auth.onAuthStateChange(
(event, session) => {
if (event === 'SIGNED_IN' || event === 'TOKEN_REFRESHED') {
setUser(session?.user ?? null);
} else if (event === 'SIGNED_OUT' || event === 'USER_DELETED') {
setUser(null);
}
setLoading(false);
}
);
return () => {
subscription.unsubscribe();
};
}, []);
return { user, loading };
}This automatically handles session refreshes and invalidations, reducing the chance of stale session errors.
Advanced notes
The session_not_found error was introduced as a security feature to better detect when JWT tokens contain references to sessions that have been revoked or expired. Previously, Supabase was returning less specific errors that could mask security issues.
Session Recovery Timing: The Supabase client library's _recoverSession() method is asynchronous. By the time you call any supabase.auth methods, the session might not have recovered yet. If you're calling auth methods immediately on app load, introduce a small delay or use onAuthStateChange() which waits for session recovery automatically.
Self-hosted Supabase: If you're running self-hosted Supabase, ensure your JWT secret is properly configured with at least 32 alphanumeric characters. Malformed secrets can cause session validation failures.
Rate Limiting: The session_not_found error is sometimes caused by rate limiting on the Supabase Auth service. If you're experiencing this error sporadically on high-traffic periods, check your project's rate limits and upgrade if needed.
Tab Synchronization: In applications with multiple browser tabs, one tab's logout can cause other tabs to encounter session_not_found since they share the same session. Implement cross-tab communication with the Broadcast Channel API to handle this gracefully.
Frequently asked questions
- What does "session_not_found" mean?
- sessions table with a unique session ID. The JWT token that your client receives contains a claim referencing this session ID. The "session_not_found" error is returned when you attempt to use an access token, but the session ID embedded in that token is no longer valid or has been deleted from the database.
- How do I fix "session_not_found"?
- The "session_not_found" error occurs when Supabase Auth detects that the session ID in your JWT token no longer exists in the auth.sessions table. This typically happens due to session expiration, token refresh failures, or URL mismatches between your Supabase configuration and frontend application.
- What causes "session_not_found"?
- User session has expired due to inactivity or token expiration time passing Session refresh mechanism failed due to network issues or service outages Mismatch between Supabase site URL (e.g., 127.0.0.1) and frontend URL (e.g., localhost) causing session validation to fail
- Is the "session_not_found" error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.
Official resources & further reading
- ๐Supabase Official Documentation
- ๐Supabase Docs: User Sessions(Official Docs)
- ๐Supabase Docs: Auth Troubleshooting(Official Docs)
- ๐Supabase Docs: JavaScript Auth Session(Official Docs)
- ๐
- ๐
- ๐
- ๐
- ๐