permission denied for sequence
The table is granted and its id counter is not. One more grant fixes it.
What is going on
A serial or bigserial column gets its numbers from a sequence, a separate database object named tablename_colname_seq. Fetching the next number requires the USAGE privilege on that sequence. The 2026 change removed the default sequence grants along with the table grants, so an insert can pass the table check and fail on the sequence.
The fix
grant usage, select on sequence public.orders_id_seq to authenticated, service_role;
Grant it to the roles that insert. The tool adds this line by itself when it sees a serial column, in the create table or in a later alter table ... add column:
-- public.orders: owner only
alter table public.orders enable row level security;
revoke all on table public.orders from anon, authenticated;
grant select, insert, update, delete on table public.orders to authenticated;
grant select, insert, update, delete on table public.orders to service_role;
grant usage, select on sequence public.orders_id_seq to authenticated, service_role;
drop policy if exists orders_select_own on public.orders;
create policy orders_select_own on public.orders
for select to authenticated
using ( (select auth.uid()) = user_id );
drop policy if exists orders_insert_own on public.orders;
create policy orders_insert_own on public.orders
for insert to authenticated
with check ( (select auth.uid()) = user_id );
drop policy if exists orders_update_own on public.orders;
create policy orders_update_own on public.orders
for update to authenticated
using ( (select auth.uid()) = user_id )
with check ( (select auth.uid()) = user_id );
drop policy if exists orders_delete_own on public.orders;
create policy orders_delete_own on public.orders
for delete to authenticated
using ( (select auth.uid()) = user_id );
Which id columns need it
| Column definition | Sequence grant needed for inserts? | How we know |
|---|---|---|
id serial / bigserial | Yes | PostgreSQL manual: nextval requires USAGE or UPDATE on the sequence. Confirmed in our test: the insert failed with permission denied for sequence s_serial_id_seq. |
id bigint generated always as identity | No, in our test | Our test inserted without any sequence grant. A Supabase maintainer's comment suggests granting sequences for identity columns as well, so we flag this as not settled by the docs. |
id uuid default gen_random_uuid() | No | No sequence is involved. |
Tests ran on 2026-11-10 against PGlite (Postgres compiled to WebAssembly), not a hosted Supabase project.
All sequences at once
Supabase's rollback note uses a schema-wide form. It grants every sequence in public to all three roles, which is broader than most apps need:
grant usage, select on all sequences in schema public to anon, authenticated, service_role;Write the fix for your tables
One table is free. The whole schema with a rollback file is $9 one-time, free during launch.
Waiting for a paste.
Who can reach each table
Your tables show up here, one row each, with a choice of who can reach them.
Parsed in your browser. Your SQL is never uploaded, and no site or database is scanned.
Questions
My table name is very long. What is the sequence called?
Postgres keeps every name within 63 bytes. For a serial column it shortens the table or column part and keeps the _seq ending. The tool follows the same rule and says so in the row. To read the real name from your database: select pg_get_serial_sequence('public.your_table', 'id');
My column uses default nextval(...) instead of serial. Is that covered?
Yes. The tool reads the sequence name from the default, also when a later alter table sets it, and grants that sequence to the roles that insert.
I added the serial column later with alter table. Is that covered?
Yes, when the alter table statement is in your paste as plain SQL. The tool follows add column, drop column, rename column and alter column type in the order they are written, and grants the sequence of a serial column that was added later. It does not run an alter table that sits inside a function or a DO block; the row for that table carries a warning instead.
Only table names were pasted. Will the tool add the sequence grant?
No. It can only see serial columns in a create table or alter table statement. Paste the full statements to get the sequence line.
Sources
- PostgreSQL manual: Sequence Manipulation Functions, read 2026-11-10
- PostgreSQL manual: Numeric Types, Serial Types, read 2026-11-10
- Supabase changelog: Breaking Change: Tables not exposed to Data and GraphQL API automatically (published 2026-04-28), read 2026-11-10
- GitHub discussion 45329 (supabase org), including maintainer replies, read 2026-11-10
- Our own test: generated SQL run against PGlite (Postgres compiled to WebAssembly), read 2026-11-10
Related
- Check the grants on a tableOne query lists every role and privilege on a table.
- The Supabase change of 30 October 2026New tables in public need explicit grants. Dates, scope and the SQL in one place.
- Lovable app says "permission denied for table"The new table has no grants. Paste it below and copy a fix prompt made for Lovable.
- Go back to automatic exposureSupabase documents the SQL. Read what it re-opens before you run it.