How to fix: Permission denied despite correct RLS, as supabase.auth.getUser() returns null on server

This Supabase/Next.js failure usually means the request reaching Supabase is anonymous or mapped to the wrong user, so 42501 permission denied or getUser null appears when RLS blocks it. Preserve the exact error, confirm the JWT and auth.uid() mapping, then patch the server client or policy before retesting.

This pattern is common in AI-built Next.js and Supabase apps because generated code often leaves auth, cookie, deployment, or type boundaries unfinished. The exact symptom matters, so preserve the original error before changing code.

Why it happens

The server-side Supabase request is not carrying a JWT Supabase can map to `auth.uid()`, so RLS treats the request as anonymous and denies the table read/write.

What to check

Confirm the server route forwards the actual Supabase-compatible JWT, including `sub`, `role: authenticated`, and any third-party provider claims Supabase expects.

Check that the RLS policy compares `auth.uid()` to the same user id stored in the table, not a Clerk-only id unless the JWT subject is mapped that way.

Verify the schema is exposed in Supabase API settings and the anon/publishable key belongs to the same project as the RLS policies.

Log the decoded JWT claims server-side without printing secrets, then compare them to the table `user_id` values.

Fix plan

Move token acquisition into the server helper used by the route and pass it through the Supabase client `Authorization` header.

Align the RLS policy and row owner field with the JWT subject Supabase receives, or add an explicit mapping table if using third-party auth.

Add a small protected-route smoke check: authenticated request can read one owned row; anonymous request is denied.

Document the required env vars and provider settings so deploy and local development use the same auth project.

When to stop guessing

If this touches auth, RLS, database writes, storage, redirects, or deployment callbacks, a build-only fix is not enough. Verify the real user path against the same Supabase project and domain that failed.

Need a second set of eyes? Paste the exact error into the free diagnosis form and get a focused rescue plan before you spend more time guessing.