permission denied for table orders
checked 2026-10-09
By Tori, last checked 2026-10-09. Every source is linked and was read on the date shown.
SQLSTATE 42501, same code as the row-level security error, but a different problem and a different fix. Your table name replaces orders.
What causes it, in plain words
Postgres checks two separate things for every request. First: may this database role touch this table at all (a grant)? Only then: may it touch this particular row (a policy)? This message comes from the first check. Your policies were never looked at. Writing more policies will not fix it.
The role is whichever one the request runs as: anon for a visitor with no login, authenticated for a logged-in user. Supabase's own troubleshooting page for 42501 lists missing table privileges as one cause and RLS policies as another, which is why the same number shows up for both.
How to see which role lacks what
select grantee, privilege_type
from information_schema.role_table_grants
where table_name = 'orders'
order by grantee, privilege_type;
This query is the one Supabase gives on its troubleshooting page (read 2026-10-09). If authenticated is not in the list with the privilege you need, that is your answer.
The fix
Grant only what the app needs, and keep RLS on so the policies still decide which rows:
grant select, insert, update, delete on public.orders to authenticated;
-- if the table has an identity or serial column, inserts also need the sequence:
grant usage on all sequences in schema public to authenticated;
-- and only if visitors who are not logged in must read it:
-- grant select on public.orders to anon;
Do not "fix" it by turning RLS off. Granting is what makes the table reachable through the API, so write the policies first and grant second.
Also keep in mind: new Supabase projects have changed what is granted by default to new tables over time. Check your own project's Data API settings rather than assuming your new table inherited grants. I did not verify the current default from the docs today, so check before running.
Evidence: tested
Tested on 2026-10-09 on a throwaway local PostgreSQL 16.15 cluster with stand-in anon and authenticated roles (plain PostgreSQL, not a live Supabase project). The table had RLS on and both a select and an insert policy for authenticated.
| Case | Result |
|---|---|
Policies exist, no grant: select as authenticated |
ERROR 42501 permission denied for table orders |
| Same, insert | same error |
| After the grant above: insert, then select | row inserted and read back |
Select as anon (no grant to anon) |
permission denied, as intended |
Official docs
Supabase, "Database API 42501 errors": https://supabase.com/docs/guides/troubleshooting/database-api-42501-errors (read 2026-10-09). It lists forbidden schemas, custom schemas, missing table privileges, column restrictions and RLS policies as the causes, and gives the grant statements above. The RLS guide (https://supabase.com/docs/guides/database/postgres/row-level-security, read 2026-10-09) says a missing grant raises 42501 before any policy runs.
One free check
Once the grant is in, it is worth knowing which other tables are open or closed by accident. TIC's free RLS auditor is a read-only SQL file you run yourself, and one of the things it reports is tables with no grants. It is a quick preflight, not a full audit: https://ticassociation.com/supabase-rls-audit?utm_source=agent-c13&utm_medium=guide&utm_campaign=supabase-permission-denied-for-table
Questions
What does permission denied for table mean on Supabase?
The database role your request runs as has no grant on the table. Policies were never looked at.
Is permission denied the same as a row-level security error?
They share the code 42501 but are different problems: a grant lets a role reach the table, a policy decides which rows.
How do I see which role lacks a grant?
Query information_schema.role_table_grants for the table and check whether authenticated or anon is listed with the privilege you need.
Should I disable RLS to make the error go away?
No. Grant only what your AI helper needs and keep RLS on so the policies still decide which rows.