Hosted Supabase Migration Blocked by 42501 Permission Denied to Change Default Privileges
#51482
Replies: 5 comments
|
The short answer on hosted Supabase: you can't Why you're getting 42501On hosted Supabase, The October 30 contextThis is directly relevant to your migration timing: changelog 45329 — on October 30, 2026, Supabase stops auto-granting Supported paths for hosted projects1. Explicit per-object grants (recommended) Instead of trying to change default privileges, grant explicitly in the migration for each object you create: -- immediately after each CREATE TABLE / CREATE FUNCTION:
GRANT SELECT, INSERT, UPDATE, DELETE ON public.my_table TO authenticated;
GRANT EXECUTE ON FUNCTION public.my_function() TO authenticated;This is what Supabase's own migration documentation recommends for the post-Oct-30 world. It's more verbose but works with the privileges 2. Supabase CLI / Dashboard There's currently no Dashboard or CLI workflow to change default privileges for Supabase-managed roles — that's the gap you've found. The CLI's 3. Support process If your migration genuinely requires changing default privileges for Supabase-managed roles (not just compensating for the Oct 30 change), that would need Supabase staff. Open a support ticket through the Dashboard (Help → Contact Support) — reference the Oct 30 changelog and explain why the per-object grants don't cover your case. What I'd do in your positionAudit whether the default-privileges change is actually necessary, or whether it's compensating for something that explicit per-object grants handle. If you're using a migration tool that generates Small disclosure: I audit Supabase/Postgres setups for production apps, so I care about exactly this class of permission boundary. The doc references above are the load-bearing part. |
|
That message comes from one check in Postgres: On a local Postgres 17.2, with So the statement to look for in the failing migration has a Commenting them out in your migration does the same thing. For objects that If the Changing the defaults of a role whose privileges I tested this on vanilla Postgres 17.2, not on a hosted project. |
|
Here is the direct breakdown for each of your three questions regarding 1. Which Role Is Authorized to Manage Default Privileges?In PostgreSQL,
-- ❌ Fails with 42501 on hosted Supabase (if targeting supabase_admin or another unowned role):
ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public
GRANT SELECT ON TABLES TO anon, authenticated;
-- ✅ Works on hosted Supabase (scopes default privileges to objects created by postgres):
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO authenticated;2. Supported CLI & Migration Workflow (
|
|
This error occurs due to the privilege inheritance rules in PostgreSQL regarding In PostgreSQL, executing
This statement typically ends up in migration files after running Here is the direct guidance for your three questions: 1. Which role is authorized to manage the relevant default privileges?The -- Fails with 42501 (postgres is not a member of supabase_admin):
ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public ...;
-- Succeeds (scoped to objects created by the postgres role):
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO authenticated;If you omit 2. Supported Dashboard or CLI workflowTo resolve this in your migration workflow:
3. Recommended support processContacting Supabase Support is not required for this issue. Supabase Support does not grant superuser privileges or add tenant roles to |
|
The answers above cover the error itself: on hosted Supabase, Per the changelog for the October 30 change, grants and RLS are separate layers: a grant decides whether a role can reach the table at all, RLS decides which rows it sees (https://supabase.com/changelog/45329-breaking-change-tables-not-exposed-to-data-and-graphql-api-automatically). The same changelog gives a rollback snippet, What I do instead, in the same migration that creates the table:
Example: create table public.orders (id bigint generated always as identity primary key, user_id uuid not null default auth.uid(), total_cents int not null);
alter table public.orders enable row level security;
create policy "own orders read" on public.orders for select to authenticated using ((select auth.uid()) = user_id);
create policy "own orders create" on public.orders for insert to authenticated with check ((select auth.uid()) = user_id);
grant select, insert on table public.orders to authenticated;
grant select, insert, update, delete on table public.orders to service_role;Then check the result with two normal users, not with the service key: sign in as user A and insert a row, sign in as user B and try to read, update and delete it through the REST API. A grant mistake shows up as a row coming back for user B, or as a write that succeeds. Do this on a staging project before and after the grants migration, so you can see that the migration fixed the 42501 and did not open anything. I ran the example above on a local PostgreSQL 18 with stand-in Disclosure: I build RowAttest, which runs that two-user check for you (free tier: one Supabase project, 10 runs a month, no card needed). Run it before and after the migration and compare the two run pages: https://rowattest.com |
Uh oh!
There was an error while loading. Please reload this page.
Hello Supabase team and community,
We are investigating a migration failure in our hosted Supabase Development project.
The migration fails before making any changes with:
SQLSTATE 42501: permission denied to change default privilegesOur investigation indicates that the
postgresrole is not a superuser and is not a member ofsupabase_admin. The migration requires a default-privileges change that the available role cannot perform.We need guidance on the supported solution for a hosted Supabase project.
We do not want to bypass managed database permission restrictions. We have not applied the failed migration, and Production must remain unchanged.
Thank you.
All reactions