Short answer
Check that the bucket name in the code matches the dashboard exactly and that the client points at the same project. If the bucket is private, add an RLS policy on storage.objects and use a signed URL instead of a public one. For new environments, create the bucket in a migration.
Rather not fix it yourself? App Fix Ticket starts with a fixed-price diagnosis, then a fixed price for the fix before any fix work.
Why the bucket isn’t found, and the fix
01
The bucket exists, but this user can’t see it
“Verify the bucket name and ensure it exists in the system, if it exists you don't have permissions to access it.” Supabase docs, Storage error codes (NoSuchBucket)
Storage answers the same way for a missing bucket and one the user can’t access. A private bucket with no SELECT policy on storage.objects looks missing to the anon and authenticated roles.
02
A public URL for a private bucket
getPublicUrl always builds a URL, even for a private bucket, and that URL fails when opened. Uploads to a private bucket also need an INSERT policy on storage.objects. Make the bucket public if the files are meant to be public, or use createSignedUrl for private files.
const { data, error } = await supabase.storage .from('invoices') // private bucket .createSignedUrl(`${user.id}/march.pdf`, 60 * 10); // valid for 10 minutes if (error) throw error; window.open(data.signedUrl);03
The name doesn’t match
The bucket id in the code must match the dashboard exactly, including case and dashes. A folder path in the bucket name, such as avatars/users, also fails: the folder belongs in the file path.
// bucket: 'avatars', file path: 'users/123.png' await supabase.storage.from('avatars').upload('users/123.png', file);04
The client points at another project
The bucket was made in one project, but SUPABASE_URL points at another one, such as local, staging or an old project. Check the URL in the running build, not only in your .env file.
05
The new environment has no bucket
A bucket made by hand in the dashboard doesn’t exist in a fresh staging project, and supabase db reset rebuilds the local stack without it. Create it in a migration, seed file or the [storage.buckets] section of supabase/config.toml so every environment has it. Keep public false unless every file may be seen by anyone with the link.
insert into storage.buckets (id, name, public) values ('avatars', 'avatars', false) -- set true only for files anyone may see on conflict (id) do nothing;
Checked against the vendor’s docs on : Supabase docs: Storage error codes; Supabase docs: Creating buckets; Supabase docs: Storage access control.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
“Very responsive, attentive to fixing bugs, and completed the project as needed! Thank you!”
Related: Supabase Storage bucket is public · Supabase new row violates row-level security · Supabase staging environment · Supabase Storage EntityTooLarge (413)