BuiltSafely

Home/Fixes

Supabase

Supabase returns empty array [] with RLS

No error, no rows: RLS is filtering everything out. Here's how to add the select policy you're missing.

  • Reviewed Oct 2026
  • 3 official sources
Sources Last checked October 16, 2026 · Sources: official docs (linked below) · Educational, not an audit

The fix

An empty array with no error usually means RLS is working and no select policy matches for this user. Check three things:

  1. The table has a select policy for the right role (usually authenticated).
  2. The user is actually signed in when the query runs.
  3. The rows really belong to that user. Check that user_id holds the user's ID.
create policy "notes select own" on public.notes
  for select to authenticated
  using ( (select auth.uid()) = user_id );

Tested October 16, 2026 against a throwaway local Supabase Postgres 17 container (no real project). With RLS on and no select policy, a signed-in user's query returned 0 rows and no error. After adding the policy, they saw their own rows. As authenticated with no user ID, the query still returned 0 rows.

Why it happens

Supabase describes a policy as adding a WHERE clause to every query (Supabase: RLS). If no policy matches, the filter removes every row, so you get []. Supabase's API keys guide puts it plainly: a missing grant returns a permission error, whereas a policy that matches no rows "returns an empty result" (Supabase: API keys).

Also check:

  • Signed out. When no one is signed in, auth.uid() returns null and an ownership check matches nothing (Supabase: RLS).
  • Wrong role. A policy written to authenticated doesn't apply to signed-out (anon) requests (Supabase: RLS).
  • Updates and deletes that "do nothing". They match zero rows the same way. Supabase notes that an update needs a matching select policy (Supabase: RLS).

A quick way to confirm it's RLS: if the same query returns rows in the dashboard's SQL editor but [] from your app, the difference is the role and policies, not the data. The SQL editor usually runs as a privileged database role (not anon or authenticated), so it isn't a fair test of what your users can see. Test with two real accounts instead, as our RLS guide describes.

What not to do

Don't "fix" it with using (true) unless the data really is public, and don't disable RLS. Supabase's Security Advisor flags always-true policies on purpose (Supabase: Advisors).

If you get an error instead of [], see our new row violates RLS fix or the 42501 fix.

Go deeper: our Supabase RLS guide.

Your turn

How long did your last empty-array mystery take to solve? Tell us what finally gave it away.

This guide is educational and based on the vendor's public docs as of the review date. Platforms change: check the linked sources. Not a security audit. Disclaimer.

The BuiltSafely weekly

One email a week. What changed, and the one fix that matters.

Platform changes that affect the security of AI-built apps, checked against official docs. Free. Unsubscribe any time.