Supabase error PGRST301 (Invalid or Undecodable JWT) explained: what it means, why it happens, and how to fix it — with copy-paste code examples.
Always send Authorization: Bearer <anon|service_role|user-jwt>. If that does not apply, regenerate or re-copy keys from Dashboard when they were rotated — the full checklist is below.
Error code: PGRST301
Official name: Invalid or Undecodable JWT
Service: Supabase
Provided JWT couldn't be decoded or it is invalid.
fetch('https://<project>.supabase.co/rest/v1/todos', {
headers: {
apikey: anonKey,
Authorization: `Bearer ${accessToken}`, // never service_role client-side
},
})
The Authorization header must carry a JWT the project's secret can verify.
The client attaches the JWT automatically; a PGRST301 usually means the session is stale - refresh first.
const { data: { session } } = await supabase.auth.getSession()
if (!session) {
await supabase.auth.signInWithPassword({ email, password })
}
const { error } = await supabase.from('todos').select('*')
if (error?.code === 'PGRST301') {
// token invalid - force re-authentication
await supabase.auth.signOut()
}
Most often this happens when missing or malformed Authorization: Bearer header, or when anon key used after the project's JWT secret was rotated.
Always send Authorization: Bearer <anon|service_role|user-jwt>.
This page documents fixes for: supabase-js.
Recommendations are editorial — DB Error Reference takes no payment or affiliate fees for tool listings.
This page is based on the official Supabase documentation linked below and adds practical troubleshooting guidance on top.