Supabase: New Row Violates Row-Level Security Policy β How to Fix It
new row violates row-level security policy for table "posts"
Row Level Security (RLS) is blocking your insert/update.
Why this happens
When RLS is enabled on a table, PostgreSQL denies all access by default unless a policy explicitly allows it. Supabase enables RLS on new tables automatically. If you havenβt created a policy that matches the current userβs role and the operation being performed (INSERT, UPDATE, DELETE), the query is rejected.
Fix 1: Add an RLS policy
-- Allow authenticated users to insert their own rows
CREATE POLICY "Users can insert own posts"
ON posts FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = user_id);
Fix 2: Check existing policies
SELECT * FROM pg_policies WHERE tablename = 'posts';
Fix 3: Temporarily disable RLS (dev only!)
ALTER TABLE posts DISABLE ROW LEVEL SECURITY;
β οΈ Never do this in production.
Alternative solutions
Use the Supabase service role key for admin operations that should bypass RLS:
import { createClient } from '@supabase/supabase-js';
const admin = createClient(url, SERVICE_ROLE_KEY);
// This bypasses RLS entirely
await admin.from('posts').insert({ title: 'Admin post' });
Only use this server-side β never expose the service role key to the client.
Prevention
- Create INSERT, SELECT, UPDATE, and DELETE policies for every table with RLS enabled β missing even one operation causes confusing errors.
- Test policies in the Supabase SQL editor with
SET role authenticated; SET request.jwt.claims = '{"sub":"user-id"}';before deploying.
Related resources
Related: Supabase: Auth Session Missing Β· Supabase vs Appwrite