Guide · Supabase
Supabase "permission denied for table" (42501) after 30 Oct 2026: how to fix it
Published 17 Oct 2026 · Last checked: 17 Oct 2026 against Supabase's changelog and docs.
From 30 October 2026, a new table you create in the public schema of an existing Supabase project is no longer reachable through the API until you grant access to it. The error you see is 42501 permission denied for table. Fix: run a GRANT for that table in the SQL Editor (statements below), and keep RLS on.
If your error says new row violates row-level security policy, that is a different problem. The grant is fine and a policy is blocking the row. See Data won't save? Row level security.
The same rule has applied since 30 May 2026 to projects created from that date, as a gradual rollout, and to any project where "Automatically expose new tables" was unticked at creation. If your project is newer than that, you may already see this error. On 30 October 2026 it reaches all existing projects.
What changed on 30 October 2026
Supabase announced a breaking change: new tables in the public schema need an explicit Postgres grant before the Data API can see them. The Data API is the layer your app calls when it uses supabase-js or sends requests to /rest/v1/ or /graphql/v1. Supabase applies this to all existing projects on 30 October 2026. (Supabase changelog)
- New table in
public: before, default projects gaveanon,authenticatedandservice_roleselect, insert, update and delete. From 30 Oct 2026, you must grant access yourself. - Tables you already have: still reachable. They keep their current grants.
- Direct Postgres connection (psql, an ORM, a connection string): not part of the Data API, so not affected.
Who is affected: apps that reach the database through the Data API. Supabase names these triggers: migrations or setup scripts that create public tables without a GRANT, and an AI coding tool, CLI script or Management API call that creates tables and expects API access.
If your builder creates tables in a Supabase project you own, and the project already exists on 30 Oct, the rule above applies to tables created after that date. Your old tables keep working.
What the error looks like
When a grant is missing, the API answers with a clear error, not a silent failure. It looks like this:
{"code":"42501","message":"permission denied for table your_table","hint":"Grant the required privileges to the current role with: GRANT SELECT ON public.your_table TO anon;"}
The hint names the role and the privilege that are missing. Your app may show this as a failed save, an empty list or a broken sign-up. The HTTP status can be 401 or 403 with the same code 42501. (Supabase: Securing your API, Supabase: 42501 errors)
Missing grant or RLS policy? How to tell
Both errors carry code 42501. Read the message.
- Missing grant: the message is
permission denied for table your_table, with a hint that gives theGRANTto run. The role cannot reach the table at all, so any read or write fails. Fix: the grant in the next section. - RLS blocking the row: the message is
new row violates row-level security policy for table "your_table", and the example in a Supabase GitHub discussion shows no hint. The role can reach the table, but a policy rejects this row, typically on INSERT or UPDATE. Fix: add or correct a policy (see this guide).
Grants and RLS are two separate layers. Grants decide whether a role can reach the table. RLS decides which rows. If the grant is missing, Postgres rejects the query before RLS comes into play. Supabase also says that anon or authenticated doing an INSERT or UPDATE without the needed RLS permission returns a 42501 error. (Supabase: 42501 errors) The RLS message text above comes from a Supabase GitHub discussion, not from the documentation.
The fix: grant, enable RLS, add a policy
Don't want to type the table name by hand? Make the SQL for your table: type the name, tick the roles, copy the SQL.
Supabase says to treat these three steps as a unit. This is the SQL from their changelog. Replace your_table with your table name. Use the table name and role shown in your own error hint. (Supabase changelog, "What to do")
- Grant the privileges the role needs:
grant select on public.your_table to anon;grant select, insert, update, delete on public.your_table to authenticated;grant select, insert, update, delete on public.your_table to service_role;
- Enable RLS:
alter table public.your_table enable row level security;
- Add the policies you need, for example:
create policy "users can read their own rows" on public.your_table for select to authenticated using (auth.uid() = user_id);
Notes:
- Keep the
anonline only if signed-out visitors should be able to read the table. Supabase says to grant the minimum privileges each role needs. (Securing your API) - Supabase's docs also show single-role forms, such as
grant select on table public.your_table to anon;. (42501 errors) - Do not copy a bulk "grant on all tables" statement as your fix. It would open every table, including private ones. Supabase publishes one only as a rollback option, in the FAQ of the changelog.
- If your table has an auto-numbered column, Supabase says new sequences also need explicit grants. The changelog's rollback block shows the
grant usage, selectform for sequences. Read it before you copy it. - The policy in step 3 is an example. Write the policy your app needs. See Users can see other users' data.
Where to run it
- Open your project in the Supabase dashboard.
- Open the SQL Editor (direct link:
https://supabase.com/dashboard/project/_/sql/new). - Paste the statements, change the names, and run them.
Supabase also says you can change table privileges in Integrations > Data API in the dashboard, or with SQL. (42501 errors) Check the menu labels on your own screen, as the dashboard can change.
Check what you already have
To see which roles have access to a table, run this in the SQL Editor:
select grantee, privilege_type from information_schema.role_table_grants where table_name = 'your_table';
Supabase also says the Data API exposure badge in the Table Editor and the Security Advisor list the tables worth reviewing. Look in your dashboard for them. (Supabase changelog)
If an AI builder creates your tables
Any tool that creates tables in your Supabase project, an AI builder included, has to include the grants for new tables. If you ask your builder to add a table, say so in the prompt. Here is a sentence you can paste:
"When you create a new table in the public schema, also write the GRANT statements for the roles that need it, enable row level security, and add the policies. Show me the SQL before you run it."
This page does not say which builder does or does not add grants for you. Check the SQL your builder produced.
Things that do not change
- Tables you already have keep their grants and stay reachable.
- Apps that talk to the database only over a direct Postgres connection are not affected.
How to confirm the fix on your live app
- Open your live app in a private window, so you are signed out.
- Sign up with a fresh email, like a new person.
- Do the thing that was failing: save the row, load the list.
- If it works, the grant is in place. If it still fails, read the message again with the comparison above.
If sign-up itself still fails, the cause may be email, not permissions. See Confirmation emails not arriving and Login broken after publish. For a full walk-through, see Test your live app like a real customer.
VibeFix's check covers the sign-up part of this: its AI agent signs up to your live app like a new person and shows whether sign-up and your pages work. It does not look inside your Supabase project or read your grants. VibeFix checks; it does not fix your app.
FAQ
Do I need to change anything for tables I already have? No. Existing tables keep their current grants and stay reachable.
Does this affect me if my app only uses a direct database connection? No. The change applies to the Data API.
Is 42501 always a grant problem? No. The same code is used when row level security blocks an INSERT or UPDATE. Read the message text.
Do I still need RLS after granting? Yes. A grant does not replace RLS. Treat grant, enable RLS and policy as one unit.
Can I get ahead of the change now? Supabase documents how to opt in early in the "Opting in on existing projects" section of its changelog. This is for advanced users: read their rollback notes first.
Sources
- Supabase changelog: tables not exposed to the Data and GraphQL API automatically
- Supabase staff discussion of the change
- Securing your API
- Database API 42501 errors
- Tables and data
- Supabase GitHub discussion with the RLS error text
VibeFix is independent. Lovable, Bolt, Replit, Base44, v0 and Supabase are trademarks of their owners.
Still stuck?
Paste your app’s link for a free sign-up check, no account needed. An AI agent signs up to your live app as a brand-new person, on a phone and a computer, and tells you whether a new person can finish.