-
Notifications
You must be signed in to change notification settings - Fork 373
Description
Describe the bug
supabase start fails on my project with a cryptic error.
Terminal output
$ supabase stop --no-backup && supabase start
Stopping containers...
Stopped supabase local development setup.
...
Applying migration 20260212131000_merge_documents_into_objects_stage2.sql...
NOTICE (00000): view "object_attributes_view" does not exist, skipping
Seeding data from supabase/seed.sql...
Starting containers...
Waiting for health checks...
Stopping containers...
Error status 400: {"statusCode":"403","error":"Unauthorized","message":"new row violates row-level security policy"}
Try rerunning the command with --debug to troubleshoot the error.
All migrations apply successfully, the seed completes, but then everything tears down. This seems to be related to the storage component, if though we're not using it at all and not touching in our migrations or anything.
I've tried removing our seed and all of the migrations and it didn't help.
I'll be happy to share any other information that might be useful, but there is really not much.
Investigation results
I've let Claude Code debug this a bit, so the results of it's investigation are below in case you find them useful.
supabase start fails during the post-startup bucket seeding phase with an RLS policy violation error. After all containers start and pass their Docker health checks, the CLI calls GET /storage/v1/bucket (via buckets.Run() → UpsertBuckets() → ListBuckets()) through Kong with the service_role
JWT. The storage-api service processes this request and internally attempts an INSERT operation that is blocked by row-level security on the storage schema tables.
The storage.buckets, storage.objects, and storage.migrations tables all have RLS enabled with zero policies (as set up by the Supabase base image init). While the table owner (supabase_storage_admin) bypasses RLS for direct connections, the request-path role used by the storage-api when
handling the incoming HTTP request does not, causing the INSERT to fail.
This happens even when no storage buckets are configured in config.toml — the ListBuckets call alone triggers the error.
Key observations from debugging:
- supabase start --exclude storage-api succeeds — all other services are healthy
- The storage container itself starts fine (its /status health check passes)
- Manually calling GET /storage/v1/bucket with the service_role JWT via curl returns [] successfully when the storage container is started manually via docker run
- The error originates from the CLI's buckets.Run() call in internal/start/start.go:1289, which runs when NoBackupVolume is true (fresh start / after --no-backup)
- Inspecting the DB confirms: storage.buckets has relrowsecurity=t, relforcerowsecurity=f, and 0 policies in pg_policies
Expected behavior
supabase start should complete successfully. The bucket seeding step should handle the case where no buckets are configured without triggering RLS violations.
System information
- Version of OS: macOS 15.7.3 (arm64)
- Version of CLI: v2.76.9
- Version of Docker: v28.5.2
- supabase/postgres: 17.6.1.063
- supabase/gotrue: v2.186.0
- postgrest/postgrest: v14.1
- supabase/realtime: v2.76.5
- supabase/storage-api: v1.37.7
- supabase/edge-runtime: v1.70.3
- supabase/studio: 2026.02.09-sha-18cc6f8
- supabase/postgres-meta: v0.95.2
- supabase/logflare: 1.31.2
- supabase/supavisor: 2.7.4
Additional context
- Workaround: Set enabled = false under [storage] in config.toml
- The project uses custom schemas (enhance, studio, private) with migrations — none touch the storage schema
- The error format is "Error status 400" (HTTP status) but the body says "statusCode":"403" — the mismatch suggests the storage-api returns HTTP 400 with a 403 error payload