"new row violates row-level security policy": what it means and the fix
Row Level Security (RLS) is a lock on each table. Once it is on, the API from the browser can read or write nothing until you add policies that say who may do what. This error means your insert did not match any policy that allows it.
The error looks like this:
new row violates row-level security policy for table
How to fix it
- Confirm RLS is on and which table. The error names the table. In the Supabase dashboard, open it and look at its policies. Turning RLS off is not the fix for a live app.
- Write an insert policy. Inserts are checked with
with check. A common shape:create policy "Users can create their own rows." on your_table for insert to authenticated with check ( (select auth.uid()) = user_id ); - Make sure the row carries the owner. The check compares
user_idto the signed-in user. If your insert leavesuser_idempty or sends someone else's, it will fail. - Check the person is signed in.
auth.uid()is empty for visitors who are not logged in, so a policy for signed-in users will refuse them. - Keep the secret key on the server. A secret (service role) key skips RLS, but it must never go into browser code. Use it only in server-side code you control.
What you should see
The same insert now succeeds when a signed-in user adds their own row, and still fails for rows that belong to someone else.
Not fixed? Bring the exact message to Bilo and we will look at it with you.
Still stuck? Paste your error into BiloQuick questions
Why can I read nothing, with no error?
With RLS on and no select policy, the API returns no rows. Add a select policy with using.
Should I just disable RLS?
Not on a table the browser can reach. Anyone with your public key could then read or change it. Write policies instead.
Why wrap auth.uid() in select?
It is the form shown in the Supabase guide for policies.
Sources and date checked
- Supabase: Row Level Security: https://supabase.com/docs/guides/database/postgres/row-level-security (checked 2026-11-01)
Written in our own words from the official pages above. Tool names are only references; we are not affiliated with them. Commands change between versions, so check the linked docs if something differs.