Guides by TICWays to earnPlatformsReality checkFree toolsRecipe Pack

Answers

permission denied for table orders

checked 2026-10-09

Short answer. This error comes from a missing grant, not a missing policy: Postgres checks whether the role may touch the table before it looks at any row policy. Check the grants, give the role only what it needs, and keep RLS on. Tested on a local PostgreSQL 16 stand-in on 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.

Keep reading