BuiltSafely

Home/Fixes

Supabase

Invalid API key (Supabase)

Wrong key, wrong header, or a secret key in the browser. Pick the key by where the code runs, without turning RLS off.

  • Docs-only
  • Reviewed Oct 2026
  • 1 official source
Sources Last checked October 19, 2026 · Badge: docs-only (official API key docs; exact error body varies by gateway) · Sources: official docs (linked below) · Educational, not an audit

The fix

Use the right key for where the code runs, send it the way Supabase expects, and keep secrets off the client.

  1. Match the project. The URL (https://YOUR_PROJECT.supabase.co) and the key must be from the same project (Supabase: API keys).
  2. Pick the key by location:
    • Browser, mobile, or anything you ship: publishable key (sb_publishable_...) or legacy anon.
    • Server, Edge Function, or cron you control: secret key (sb_secret_...) or legacy service_role.
  3. Send new-style keys on the apikey header, not as Authorization: Bearer. Publishable and secret keys "aren't JWTs"; anything that tries to verify one as a JWT fails (Supabase: API keys).
  4. Copy cleanly. No quotes, spaces, or truncated values in .env. Restart the dev server after changing env vars.
  5. If a secret key was ever in the client, a log, or git: treat it as leaked. Fix the cause, create a new secret key, replace it, confirm every backend uses the new one, then retire the old key (Supabase: API keys).
# Browser-safe (prefix per your framework)
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...

# Server-only. Never prefix these, or your bundler will ship the key.
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SECRET_KEY=sb_secret_...

Why it happens

An API key tells Supabase which application is calling. It is not the signed-in user. Common misconfigurations:

  • Secret key in the browser. Supabase matches on the User-Agent and returns HTTP 401 Unauthorized for a secret key in a browser (Supabase: API keys).
  • Wrong header for new keys. New publishable/secret keys go on apikey, not Authorization: Bearer (Supabase: API keys).
  • Legacy vs new keys mixed up. Tutorials that show a long eyJ... JWT are describing legacy anon / service_role keys. New keys are short sb_publishable_... / sb_secret_... strings (Supabase: API keys).
  • Key from another project, or a key that was rotated and deleted.

What not to do

  • Don't disable RLS to "get past" a key error.
  • Don't put a secret or service_role key in frontend code, VITE_ / NEXT_PUBLIC_ variables, or the repo (Supabase: API keys).
  • Don't log full keys. Supabase says not to log a key even if it looks invalid (Supabase: API keys).

AI prompt

My Supabase client returns Invalid API key or HTTP 401 on startup.
Check: project URL matches the key's project; browser code uses only the publishable (or legacy anon) key; new-style keys are sent on the apikey header; no sb_secret_ or service_role value is in client env vars or the bundle.
Do not disable RLS. Do not move a secret key into the client.
Show changes first and wait for my OK. If a secret was exposed, remind me to rotate it.

How to verify

  1. Signed out, confirm the app still loads public data you intend to be public (publishable key + RLS).
  2. Sign in as user A, then as user B: each sees only their own private rows (our RLS guide).
  3. After a production build, search the output for sb_secret_ and for JWTs whose role is service_role (secret key in frontend bundle).

Is the publishable key safe? · Secret key in frontend bundle · JWT expired

Your turn

Was it a new sb_ key, a legacy JWT key, or a secret key that had slipped into the browser? Tell us which. We'll lead with that case.

This guide is educational and based on the vendor's public docs as of the review date. Platforms change: check the linked sources. Not a security audit. Disclaimer.

The BuiltSafely weekly

One email a week. What changed, and the one fix that matters.

Platform changes that affect the security of AI-built apps, checked against official docs. Free. Unsubscribe any time.