Error fixes / Supabase

Supabase

Supabase: JWT expired

The access token the app sent is no longer valid.

The error

JWT expired

What it means

Supabase access tokens are short lived. The API returns JWT expired when the app keeps using an old token and does not refresh the session. It also happens if the system clock on the device is far ahead, or if a token was copied into an environment variable and has gone stale.

Fix

  1. Use the Supabase client auth helpers rather than saving the access token in local storage yourself. The client refreshes it.
  2. On a server, read the session per request. Do not cache the JWT in a module-level variable. That value is shared across requests and goes stale.
  3. If the error appears immediately, check the device clock, then sign out and sign in again.
  4. Confirm the site URL and redirect URLs so the refresh cookie can be set on the real domain.
  5. After a fix, retry a data request. A single refreshed session should clear the error until it expires again, which is normal.

Prompt

Fix prompt
Paste into Cursor or Claude Code
API calls fail with "JWT expired".

Stop storing the access token in a global variable or a hand-rolled localStorage item. Use the Supabase client's session handling so the token refreshes. On the server, load the session inside the request and pass that client into the query. Do not lengthen the JWT lifetime as the fix. Do not print tokens. Tell me which file was caching the session.

Questions

Is a short-lived JWT a bug?

No. Access tokens are meant to expire. The bug is usually that the app never refreshes the session, or that it reuses one token for every visitor.

Can I put a service role key in the header to skip this?

Not in the browser. That key ignores RLS. Refresh the user session instead.

Why did it start after I deployed?

The server may be reusing a token captured at build time or in a module scope. Read the user session on each request, in the production environment.

Related fixes

Source: Supabase docs: User sessions. Updated 14 October 2026.