Skip to content

JavaScript and API errorTypeError: “Failed to fetch”

A fetch() call rejects with TypeError: Failed to fetch in Chrome, NetworkError when attempting to fetch resource in Firefox, or Load failed in Safari. fetch() only rejects like this when no usable response came back: an HTTP 404 or 500 does not cause it.

Short answer

Check the console next to the error: a CORS message means the server must allow your origin. An http:// URL from an https:// page is blocked as mixed content. Also check that the URL is right and complete, the server is up, the user is online, and no ad blocker or browser extension is blocking the request (common for URLs with words like analytics or track). For real network drops, catch the error and show a retry instead of a blank screen.

Why fetch rejected, and the fix

  1. 01

    No usable response: CORS, network or blocked request

    “The promise returned by fetch() will reject on some errors, such as a network error or a bad scheme.” MDN, Using the Fetch API

    fetch() rejects only when the request could not complete: the network is down, the server is unreachable, CORS hides the response, or the browser blocked the request. The message is the same for all of them, so the console and Network tab are where the real reason shows.

  2. 02

    The user is offline or the connection dropped

    “There is a network error (for example, because the device does not have connectivity).” MDN, Window: fetch() method, exceptions

    On phones and flaky Wi-Fi, a request can fail mid-way. Treat it as an expected state: catch it, tell the user, and let them retry.

    async function load() {
      try {
        const res = await fetch('/api/items');
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        return await res.json();
      } catch (err) {
        if (err instanceof TypeError) showBanner('You seem to be offline. Try again.');
        throw err;
      }
    }
  3. 03

    A wrong, relative or http:// URL

    A wrong host, a typo, or a base URL pointing at a host that does not exist (a DNS failure) makes fetch reject, and an http:// API from an https:// page is blocked as mixed content. A relative URL such as undefined/api/items gives a 404 instead, so log the full URL you are calling once, in the deployed build.

    const base = API_URL ?? '';
    if (base && !base.startsWith('https://') && !base.startsWith('/')) {
      console.warn('API URL is not https:', base);
    }
  4. 04

    An ad blocker or extension cancelled it

    Privacy extensions block requests to URLs that look like tracking, such as /analytics, /track or known third-party hosts. It fails only for some users. Test in a private window without extensions, and give your own endpoints neutral names.

Checked against the vendor’s docs on : MDN: Using the Fetch API; MDN: Window fetch() method.

Rather hand it over?

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

Related: “Blocked by CORS policy” · Axios “Network Error” · Supabase “Failed to fetch” in a published app

Questions

More on this error

Does a 404 or 500 cause Failed to fetch?

No. Those come back as a normal response with res.ok set to false. Failed to fetch means no usable response at all, so check res.ok separately for HTTP errors.

Why does it fail only for some users?

Usually an ad blocker, a corporate proxy or firewall, or a flaky mobile connection. Ask for the browser and extensions in use, and log the error with the URL.

Can you fix it for me?

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. 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.

A different error?

Describe it and get a written quote

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; Simon replies by email, usually within one business day.