aiRepoFix / How-to fixes
Supabase error 42501 on a new table after Oct 30, 2026: how to fix it
Last checked against vendor documentation: October 17, 2026.
Short answer: Supabase says that from October 30, 2026, new tables in the public schema are no longer exposed to the Data API automatically on existing projects. A table with no explicit grant fails with Postgres error 42501 (permission denied for table ...). The fix is a GRANT for the roles that need access, written into the same migration that creates the table, with row level security (RLS) turned on and policies added.
Who this affects, and when
- Affected: apps that read or write the database through Supabase's Data API:
supabase-jsor another client library, direct calls to/rest/v1/, or GraphQL. - Not affected: apps that only connect straight to Postgres (psql, an ORM, or a server with a connection string). Existing tables also keep the grants they have today.
- Dates, per Supabase's changelog: opt-in at project creation from April 28, 2026; the default for new projects from May 30, 2026 (gradual rollout); enforced on all existing projects on October 30, 2026. If your project is newer, or you opted in, you may already see this behavior.
When this page was last checked (October 17, 2026), the October 30 date had not arrived yet. If it is after that date, re-read the changelog linked below in case Supabase has updated the plan.
How to tell it is this problem
- The error code is
42501and the message sayspermission denied for table your_table. Some clients show it as a 401 or 403. - It happens on a table that was created recently (for example by your AI tool). Older tables still work.
- The response usually includes a hint naming the exact grant that is missing:
{
"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;"
}
To see what a table currently grants, run this in the SQL Editor:
select grantee, privilege_type
from information_schema.role_table_grants
where table_name = 'your_table';
If an older table gives 42501, it is probably not this change. Supabase lists other causes: querying a restricted schema such as auth or vault, querying a custom schema that is not exposed to the API, column-level restrictions (including select *), and RLS blocking an insert or update. See the troubleshooting guide in the sources. Our page on empty results and RLS policy errors covers the RLS case.
The fix: grant, enable RLS, add policies
Supabase treats these three steps as a unit. If the grant is missing, Postgres rejects the query before RLS is even checked. Replace your_table and the policy to match your app:
-- 1. Grant only what each 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;
-- 2. Turn on row level security
alter table public.your_table enable row level security;
-- 3. Add the policies you need (example: users read their own rows)
create policy "users can read their own rows"
on public.your_table
for select
to authenticated
using ((select auth.uid()) = user_id);
anonis the signed-out visitor. Only grant toanonif signed-out people are meant to read that table. If every table in your app needs a login, leaveanonout.authenticatedis a signed-in user. Grant only the operations your app actually uses. RLS policies then decide which rows each user can touch.service_roleis for server-side code only. It needs the grant too: Supabase notes a missing grant gives a permission error even forservice_role. Never put that key in browser code.- Tables with a
serialorbigserialid: The opt-in statements Supabase documents also remove automatic grants on sequences. If an insert fails withpermission denied for sequence ..., addgrant usage, select on sequence public.your_table_id_seq to authenticated;(use your sequence name). In our check on a plain PostgreSQL test database, a table using an identity column did not need this, but test your own schema.
New functions (RPC). Supabase's own setting is called "Automatically expose new tables and functions", and its Securing your API guide revokes the automatic execute permission on functions too. So if your app calls a database function with supabase.rpc(), a new function may also need a grant, for example grant execute on function public.your_function() to authenticated;. Grant it only to the roles that should call it. Row level security does not apply to functions, so be careful with who gets execute, and review any security definer function. In our test on a plain PostgreSQL database, a function with execute revoked failed with permission denied for function until the grant was added. We could not test how Supabase handles new functions after October 30, so check the changelog and your own project.
A grant only opens the door to the table. Without RLS and policies, any role with the grant can read and write every row. Supabase's guide says to enable RLS on every table you expose.
Where to put it so it survives redeploys
Put the grants in the same migration file that creates the table, right next to the enable row level security line and the policies. Supabase recommends bundling grants with your RLS setup in one migration so the change is reproducible across environments. If your project uses the Supabase CLI, migrations live in supabase/migrations/.
For Lovable, Bolt and other AI-tool users: the tool creates your tables, so it has to write the grants. Supabase suggests updating the tool's instructions (or adopting its agent skill) so the grants step is included. A prompt you can paste into your tool:
Whenever you create or change a table in the public schema, add explicit GRANT
statements in the same migration, enable row level security, and add policies.
Grant to anon only if I say the data is public. Never turn RLS off to fix an error.
After the tool creates a table, open the generated migration and check that the grant lines are there.
Before October 30: test it now
- Supabase's Security Advisor flags affected tables until the change lands, and the Table Editor shows a Data API exposure badge. Review what it lists.
- You can switch an existing project to the new behavior early. Try it on a copy or staging project first, because it changes what future tables can do. Supabase documents the statements in its changelog. Existing tables keep their grants.
- Supabase also documents a rollback that restores the old defaults for projects that opted in early. It is a reasonable stopgap, but it brings back the automatic exposure this change is meant to remove, so treat it as temporary.
Common mistakes
- Granting everything to
anonto make the error go away. That can make private data readable or writable by anyone with your public key, unless RLS stops it. - Turning RLS off. The grant fixes 42501. Turning RLS off removes the row-level protection.
- Fixing it only in the dashboard. A grant run once by hand is not in your migration files, so a new environment, branch or rebuilt project will hit the error again.
- Assuming it is the grant when it is an RLS error.
permission denied for tableis a grant problem.new row violates row-level security policyis a policy problem.
What you can do yourself, and when it is a code change. Adding grants to one or two tables is a few lines of SQL you can run in the Supabase SQL Editor. It becomes a code change when many migrations need retrofitting, when code or a script creates tables at runtime, when you are not sure which roles or policies each table needs (wrong policies can expose data or lock users out), or when the app queries a custom schema. We work from your GitHub repo and deliver a pull request. We can't change settings inside your Supabase dashboard; if a fix needs one, we say so in the pull request notes and you make that change.
Sources
This page is based on the vendor documentation below. Menu names and defaults change, so check the source if something on your screen looks different.
- Supabase changelog: Breaking Change: Tables not exposed to Data and GraphQL API automatically
- Supabase troubleshooting: Database API 42501 errors
- Supabase docs: Securing your API (grants, RLS, revoking default privileges)
- Supabase docs: Row Level Security
- Supabase docs: API keys (publishable and secret keys, roles)
Last checked: October 17, 2026. aiRepoFix is not affiliated with or endorsed by the companies named on this page.