supabase error

Supabase: new row violates row-level security policy

The error

new row violates row-level security policy for table "todos"

What it means

You tried to INSERT a row, RLS is enabled on the table, and no policy permits the current user to write what you tried to write.

When you enable RLS, every action defaults to denied. INSERT requires a WITH CHECK policy that returns true for the row you’re inserting. Common mistake: a SELECT policy exists, but no INSERT policy, so reads work but writes fail.

The fix

Add an INSERT policy with a WITH CHECK clause
-- Allow users to insert their own todo
CREATE POLICY "users insert own todo"
  ON public.todos
  FOR INSERT
  WITH CHECK (auth.uid() = user_id);

-- And make sure the inserted row sets user_id from the JWT, not the client
-- (you can use a default: user_id uuid DEFAULT auth.uid())

Also check

Common adjacent root causes when the obvious fix doesn’t work.

  • 01Are you signed in? auth.uid() returns NULL for unauthenticated users; most policies fail.
  • 02Did your client set the row’s user_id field correctly? Many clients send NULL by default.
  • 03Are there separate policies for INSERT, UPDATE, DELETE? FOR ALL covers all four; FOR INSERT covers only inserts.

Scan for related issues

This error is in our supabase scanner. Run a free scan to find what else is misconfigured in the same area.

FAQ

Frequently asked questions

Can I just disable RLS to make this go away?
You can, but then your table is open to anyone with your anon key — which ships in your client bundle. Almost always the wrong move. Add the right policy instead.
How do I debug which policy is blocking me?
Run EXPLAIN on the query in Supabase SQL Editor — it shows which policies were evaluated. Or temporarily switch the role to postgres and rerun: if it works, RLS is the cause.