Guide
Supabase Storage images not loading on your live app
Updated
Images in Supabase Storage can fail to load when the bucket is private and the image is requested through a public URL, when the signed URL has expired, or when image transformations are disabled. This applies to apps made with AI app builders that use Supabase as their backend.
Fixed in your code, then tested live. Check my app free
Why it happens
Supabase Storage has two access models. A private bucket puts every operation, including downloads, under access control, so a plain public link will not serve the file. Buckets are private by default. A public bucket bypasses access controls for retrieving and serving files, so anyone with the asset URL can open it.
Possible causes
- The bucket is private, so downloads are subject to access control and a public URL will not serve the file.
- The image link points at a private bucket, which is only reachable with a signed URL or an authorization header containing the user's JWT.
- The image is served through a signed URL that has expired, because signed URLs can be accessed only for a limited time.
- The image is served through a signed URL whose signing key was revoked, which makes existing signed URLs return an InvalidJWT error.
- Image transformations are disabled for the project, so transformation requests are not processed.
Official fix steps
- For a private bucket, create a signed URL with the createSignedUrl method that can be accessed for a limited time. (supabase.com)
- For a private bucket, download the asset with an authorization header containing your user's JWT. (supabase.com)
- Use getPublicUrl to generate the public URL for a file in a public bucket. (supabase.com)
- If the asset has no meaningful per-user access restriction, prefer a public bucket. (supabase.com)
- If you use transformed images, enable the Enable Image Transformations option under Storage > Settings in the dashboard. Image resizing is currently enabled for Pro Plan and above. (supabase.com)
You can't see it yourself
You're signed in, your customers aren't. Your own account is already allowed in, and your browser may hold a cached copy of the image. A new customer arrives with no session and no cached copy, so a private bucket or an expired link can break the image for them while it still looks fine to you.
What to do next
App broke after you published it? Our AI agent fixes it in your code, then tests your live app again so you see the result yourself. The first check is free.
Fixed in your code, then tested live. Check my app free
Related: Supabase "permission denied for table" (42501) fix · Works in the preview but not after publishing · Vibe coded app checklist: what new users hit
Sources
VibeFix's check can show this on your live app: its AI agent signs up to your app like a new person, uses it on a phone and a computer, and shows what breaks.
Last checked: 1 November 2026, against the sources listed above.
VibeFix is independent. Lovable, Bolt, Replit, Base44, v0 and Supabase are trademarks of their owners.
Want it fixed?
Our AI agent fixes it in your code and tests your live app again. See pricing.
It starts with a free check that confirms the problem on your live app, no account needed.