← All errors · SupabaseSupabase database & RLS errors
RLS Disabled in Public: Table is public, but RLS has not been enabled
Exact error
RLS Disabled in Public Table `public.profiles` is public, but RLS has not been enabled. Level: ERROR (lint 0013_rls_disabled_in_public)
What it means
This is a Supabase Security Advisor warning, not a crash. A table in a schema exposed to the Data API (usually public) has Row Level Security turned off while the anon or authenticated role can still read it. Your anon key ships in your frontend, so anyone who has it can read, and often insert, update and delete, every row in that table through the API.
Likely causes
- The table was created in the SQL Editor, a migration, or by an AI tool (Lovable, Bolt, Cursor) instead of the Table Editor. Tables created in the Dashboard have RLS on by default; SQL-created tables do not.
- RLS was turned off while debugging an "empty array" or "violates row-level security policy" error and never turned back on.
- The project still grants select, insert, update and delete on new public tables to anon and authenticated by default.
How to fix it
Open Advisors → Security Advisor in the Supabase Dashboard to see every flagged table. Each one needs RLS turned on.
Enable RLS on each flagged table in the SQL Editor:
alter table public.profiles enable row level security;Add policies for what the app actually needs. Once RLS is on, the anon and authenticated roles see nothing until a policy allows it. For example, users can read and update only their own profile:
create policy "Users can read own profile" on public.profiles for select to authenticated using ( (select auth.uid()) = id ); create policy "Users can update own profile" on public.profiles for update to authenticated using ( (select auth.uid()) = id ) with check ( (select auth.uid()) = id );Tighten grants too. Policies do not remove table grants, so give each role only what it needs:
revoke all on table public.profiles from anon, authenticated; grant select, update on table public.profiles to authenticated;If you never use the Data API (your server connects with a database connection string only), you can instead remove public from Exposed schemas in the API settings. Only do this if no client code uses supabase.from(...).
Test as a signed-out and a signed-in user, then rerun the Security Advisor to confirm the warning is gone. If the app now shows empty lists, a policy is missing (see the related empty array fix).
Prevent this next time
- Keep schema and RLS policies in migrations (`supabase migration new`) instead of editing production by hand.
- Test each policy as both an anonymous and a signed-in user before shipping.
FAQ
What does "RLS Disabled in Public: Table is public, but RLS has not been enabled" mean?
This is a Supabase Security Advisor warning, not a crash. A table in a schema exposed to the Data API (usually public) has Row Level Security turned off while the anon or authenticated role can still read it. Your anon key ships in your frontend, so anyone who has it can read, and often insert, update and delete, every row in that table through the API.
What usually causes it?
The table was created in the SQL Editor, a migration, or by an AI tool (Lovable, Bolt, Cursor) instead of the Table Editor. Tables created in the Dashboard have RLS on by default; SQL-created tables do not. RLS was turned off while debugging an "empty array" or "violates row-level security policy" error and never turned back on. The project still grants select, insert, update and delete on new public tables to anon and authenticated by default.
How do I fix it?
1. Open Advisors → Security Advisor in the Supabase Dashboard to see every flagged table. Each one needs RLS turned on. 2. Enable RLS on each flagged table in the SQL Editor: 3. Add policies for what the app actually needs. Once RLS is on, the anon and authenticated roles see nothing until a policy allows it. For example, users can read and update only their own profile: 4. Tighten grants too. Policies do not remove table grants, so give each role only what it needs: 5. If you never use the Data API (your server connects with a database connection string only), you can instead remove public from Exposed schemas in the API settings. Only do this if no client code uses supabase.from(...). 6. Test as a signed-out and a signed-in user, then rerun the Security Advisor to confirm the warning is gone. If the app now shows empty lists, a policy is missing (see the related empty array fix).
Last checked against official docs on . Sources: Supabase lint 0013: RLS Disabled in Public, Supabase docs: Row Level Security.
Related errors
- new row violates row-level security policy for table
- Supabase select returns an empty array (no error)
- relation "public.x" does not exist
More Supabase errors and fixes →
Tools that help
- Railway: Deploy backends and databases; new users get $20 credit.
Some links on this page are affiliate links: if you sign up or buy through them, FixStack may earn a commission at no extra cost to you. Learn more.
Get new fixes weekly
No spam. Unsubscribe anytime. Privacy