Supabase "Failed to fetch" error — causes and fixes
"TypeError: Failed to fetch" means the browser never got an answer from Supabase. Here's how to find out why in a few minutes, and fix the usual causes one by one.
Your app calls Supabase and the console says:
TypeError: Failed to fetch
Sometimes with friends: AuthRetryableFetchError, NetworkError when attempting to fetch resource, Load failed on Safari, or a red CORS message.
The message is frustrating because it says almost nothing. Here's what it does say: the browser tried to send a request and never got a usable answer back. It's not "Supabase said no" — that would be a 401, 403 or 400 with a message. It's "something stopped the request from completing at all".
That narrows things down a lot. Below is how to find which of the usual causes it is, quickly.
Step 1: Look at the failed request
Open your app in a desktop browser, right-click → Inspect, go to the Network tab, and reload. Find the request in red to supabase.co (or your custom Supabase domain). Click it and look at:
- The full URL. Does it start with
https://<your-project-ref>.supabase.co? Or does it sayundefined,localhost, or something odd? - The status. "(failed)", "CORS error", "(blocked)", a status code, or nothing at all.
- The timing. Did it fail immediately, or after waiting a long time?
Each combination points to a different cause.
Cause 1: The Supabase URL in your app is wrong or missing
Look for: the request URL contains undefined, or goes to your own site instead of supabase.co, or the project ref doesn't match your project.
Your app builds the Supabase client from two settings: the project URL and the public key. If the URL setting is missing on the live site, requests go nowhere useful and fail.
This usually happens when the app is deployed somewhere new (Vercel, Netlify) and the environment variables weren't copied over, or when they don't have the right prefix. For Vite apps (Lovable and Bolt use Vite), browser code can only read variables starting with VITE_; for Next.js it's NEXT_PUBLIC_.
Fix: set the variables on your host with exactly the names your code reads, for example VITE_SUPABASE_URL and VITE_SUPABASE_PUBLISHABLE_KEY, and rebuild. Then check the request URL again. Copy the URL from Supabase's dashboard (the project's API settings) rather than typing it — one wrong character in the project ref is enough.
Cause 2: The Supabase project is paused
Look for: the URL is right, but every request fails or hangs. Nothing in the code changed recently. It's a Free plan project.
Supabase pauses Free plan projects that have low activity over a 7-day period. A paused project doesn't answer API requests, and browsers often report that as a generic network failure or even a CORS error.
Fix: open the Supabase dashboard. A paused project is marked as such, with an option to restore it. Restoring takes a few minutes; your data is kept. Our guide to restoring a paused Supabase project covers the details and how to prevent it.
Cause 3: Supabase is having an outage
Look for: the URL is right, the project isn't paused, and it suddenly stopped working for everyone.
Fix: check our live Supabase status, which shows Supabase's official status page and our own check every 5 minutes. If Supabase is down, there's nothing to fix in your code — wait, and let your users know.
Cause 4: A CORS error that isn't really about CORS
Look for: the console mentions CORS, "No 'Access-Control-Allow-Origin' header", or "blocked by CORS policy".
For calls from the browser to Supabase's own APIs (database, auth, storage), hosted Supabase projects already allow requests from browsers. So a CORS message there usually means the request failed for another reason — a wrong URL, a paused project — and the browser reports it as CORS because the error response didn't include the usual headers. Go back to causes 1–3.
There's one case where CORS is genuinely yours to fix: Supabase Edge Functions. If your app calls https://<ref>.supabase.co/functions/v1/your-function from the browser, the function itself must answer the browser's preflight OPTIONS request and include CORS headers in its responses. Supabase's Edge Functions docs show the pattern. If you used an AI builder, you can ask it:
My Supabase Edge Function "<name>" fails from the browser with a CORS error.
Make it answer OPTIONS requests and add Access-Control-Allow-Origin, Access-Control-Allow-Headers
(authorization, x-client-info, apikey, content-type) and Access-Control-Allow-Methods to every response,
including error responses.
The last part — including error responses — is the one most often forgotten. If the function crashes and returns an error without CORS headers, the browser shows a CORS error instead of the real one, which sends you looking in the wrong place. Check the function's logs in the Supabase dashboard to see the real error.
Cause 5: Something on the visitor's side blocks the request
Look for: it works for you but not for some users, or only fails in one browser.
- Ad blockers and privacy extensions sometimes block requests to third-party domains. Try a private window with extensions off.
- Company or school networks may block unknown domains.
- VPNs or DNS filters can block or slow down requests.
Fix: there's not much to fix in code. If it's one user, ask them to try another network or browser. If it's many users in one place, Supabase supports custom domains on paid plans, which can help when a network blocks supabase.co specifically — check Supabase's docs for the current requirements.
Cause 6: The request is too slow, or gets cancelled
Look for: the request is pending for a long time, then fails; or fails only on slow connections.
- A very slow database query can take long enough that the request is cancelled. Check the query performance tools in the Supabase dashboard, and add indexes for columns you filter on.
- If the user navigates away or the component unmounts mid-request, some code reports that as a failed fetch. That's often harmless — but make sure your app doesn't show a scary error for it.
Cause 7: Mixed content or a wrong protocol
Look for: the request URL starts with http:// while your site is on https://.
Browsers block insecure requests from secure pages. Make sure the Supabase URL in your settings starts with https://.
Test Supabase without your app
To be sure whether the problem is your app or Supabase, call the project directly from a terminal, using your project URL and its public (anon or publishable) key:
curl -i "https://<project-ref>.supabase.co/rest/v1/" -H "apikey: <your-public-key>"
If this answers quickly with any HTTP status, Supabase is reachable and the problem is in how your app makes the request — usually cause 1, 4 or 5. If it hangs or can't connect, the project is paused, Supabase is having trouble, or your network blocks it.
A prompt for your AI builder
If you're using Lovable, Bolt or Cursor, give it the evidence instead of "Supabase doesn't work":
Requests from my app to Supabase fail with "TypeError: Failed to fetch".
The failing request URL is: <paste it>
Its status in the Network tab is: <failed / CORS error / pending then failed>
The project is not paused and Supabase status is fine.
Find the cause. If an environment variable is missing on my host, tell me its exact name.
Also make the app show a clear "Can't reach the server, please try again" message instead of a blank page or a raw error.
Making this error less painful next time
A few habits help:
- Show a friendly message. Wrap Supabase calls so a network failure shows "Can't reach the server — please try again" instead of a broken page.
- Handle the paused case. A paused Free project is a predictable event; don't let it take the whole app down silently.
- Know before your users do. Pingbuddy watches your app every 5 minutes, opens it in a real browser to catch blank screens and on-screen errors, tells you when your Supabase project is paused, and tells you when Supabase itself has an outage — with "it's not your code" when that's the case. It's free for up to 20 sites.
You can also run a free checkup of your app now. Among other things, it checks whether your app's Supabase project is paused.
Quick checklist
- Network tab: is the request URL correct and
https://? - Environment variables on the host: right names, right prefix, rebuilt?
- Supabase dashboard: is the project paused?
- Supabase status: is there an outage?
- CORS message on an Edge Function: handle
OPTIONSand add headers to every response, including errors. - Only some users: ad blockers, VPNs, company networks.