DEV Community

Cenk KURTOĞLU
Cenk KURTOĞLU

Posted on

Supabase Error 42501 "permission denied for table" — The October 30 Fix (Copy-Paste SQL)

If your Supabase app suddenly starts throwing 42501: permission denied for table errors on October 30, 2026, nothing is broken. Supabase is tightening default table permissions, and apps that relied on the old defaults will break.

Here's the 60-second diagnosis and the exact SQL to fix it.

Why this happens

Since the beginning, Supabase auto-granted anon, authenticated, and service_role access to every table you created. On October 30, 2026, that stops: new tables in existing projects will no longer get automatic grants.

If your app creates tables after that date — through migrations, through the dashboard, or through an AI coding tool — every query against those tables will fail with:

PostgresError: 42501: permission denied for table your_table
Enter fullscreen mode Exit fullscreen mode

The 60-second check

Run this in your SQL editor today:

select grantee, table_name, privilege_type
from information_schema.role_table_grants
where table_schema = 'public'
  and grantee in ('anon', 'authenticated')
order by table_name;
Enter fullscreen mode Exit fullscreen mode

If you get rows for every table — you're fine. If you get zero rows, your app breaks on October 30.

The fix: explicit GRANTs

The pattern depends on what your tables need. The safe default that matches old behavior:

-- Read access for client roles
grant select on all tables in schema public to anon, authenticated;

-- Write access for logged-in users (if your app writes from the client)
grant insert, update, delete on all tables in schema public to authenticated;
Enter fullscreen mode Exit fullscreen mode

But don't blind-copy that. The right move is to grant only what your RLS policies already assume:

Policy type Minimum grant
for select to anon grant select on <table> to anon
for all to authenticated grant select, insert, update, delete on <table> to authenticated
Insert-only (logs, events) grant insert on <table> to authenticated

For future tables, lock it in:

alter default privileges in schema public
  grant select on tables to anon, authenticated;

alter default privileges in schema public
  grant insert, update, delete on tables to authenticated;
Enter fullscreen mode Exit fullscreen mode

Test before October 30

begin;
-- Simulate what Oct 30 does to new tables
revoke all on all tables in schema public from anon, authenticated;

set local role authenticated;
select * from public.your_table limit 1;
-- permission denied = this table relies on defaults
rollback;
Enter fullscreen mode Exit fullscreen mode

The RLS part

Adding a GRANT means the table is reachable. Your RLS policies decide which rows are visible. Both layers need to be right:

GRANT (can you touch this table?)
  → RLS policy (which rows can you see?)
    → query succeeds or fails
Enter fullscreen mode Exit fullscreen mode

A GRANT without a matching RLS policy = full table access. An RLS policy without a GRANT = the same 42501 error.

The full pre-flight checklist

For a complete migration kit — including 5 paste-ready GRANT templates (read-only, client-write, service-role-only, admin-panel, multi-tenant), a testing script that simulates the October 30 defaults against your schema, and a 15-minute checklist — grab the Supabase October 30 Migration Kit ($19, instant download).

Or run the free readiness check agent-side: github.com/cekuu35/alexa-mcp-server (oct30_readiness_check tool).

Don't panic-fix with GRANT ALL

The worst instinct when 42501 hits: grant all on all tables to anon. That "fixes" the error by removing the security layer. October 30 is a hardening event — the correct response is to make your implicit permissions explicit, not to open everything wider than before.


References: Supabase discussion #51482 (first permission-denied reports), the official docs on table GRANTs, and hands-on testing against pre-Oct-30 schemas.

Top comments (0)