What this means
The Supabase advisor reports 'RLS Enabled No Policy' (lint 0008_rls_enabled_no_policy) when a table has row-level security switched on but no policies. In that state Postgres applies a default-deny rule: no rows are visible or can be modified through the API. Reads do not fail, they return an empty array, which is why this looks like a bug in your query. It is the safe failure, and the fix is to add a policy.
Why it happens
- An AI tool or the dashboard enabled RLS when it created the table, and no policy was written afterwards.
- A policy exists, but only for another role. A policy written to authenticated returns nothing to a visitor who is not signed in.
- The policy compares auth.uid() with a column that is empty in older rows, so those rows never match.
- The request reaches Supabase without the user's session, so it runs as anon. This is common in server routes and edge functions that build their own client.
- You have a filter in the query that matches nothing. Rule this out first, because it produces the same empty array.
How to fix it
- 1Decide who should see the rows: only the owner, members of a team, or everyone.
- 2Make sure the table has a column that records the owner, such as user_id, and that existing rows have it filled in.
- 3Create a SELECT policy for that rule. Add INSERT, UPDATE and DELETE policies for the writes your app performs.
- 4If the table is meant to be reachable only from your server, keep it locked and make that intent explicit with a policy that uses false.
create policy "Users can read their own notes"
on public.notes for select
to authenticated
using ((select auth.uid()) = user_id);
create policy "No API access"
on public.internal_audit_log for select
using (false);How to confirm the fix
Test both directions on your own project. Signed in, you should get your rows. Signed out, the same request should still return an empty array. Find your project URL and publishable (anon) key in the dashboard, then run the request below without a user token.
curl 'https://YOUR-PROJECT.supabase.co/rest/v1/notes?select=*&limit=5' \
-H 'apikey: YOUR_PUBLISHABLE_OR_ANON_KEY'Frequently asked questions
Why is there no error message?
For reads, RLS filters rows instead of failing. A query that may see zero rows returns zero rows. Writes are different and return a row-level security error.
Is the advisor warning a security problem?
No. Supabase rates it as informational. The table is locked, not exposed. It is flagged because your app probably cannot use the table until you add a policy.
Supabase's troubleshooting page says to disable RLS to test. Should I?
Only on a development project with no real data, and only for a moment. On a live project it exposes the table while it is off. Testing as a specific role in the SQL editor gives you the same answer safely.