All posts
javascriptnetworking

Fixing "TypeError: Failed to fetch" in JavaScript

Why Chrome's Failed to fetch error happens, how it relates to CORS and connectivity, and how to diagnose the real cause.

SR

Suhail Roushan

August 6, 2026

·
4 min read
·
0 views

TypeError: Failed to fetch is Chrome's phrasing of the same generic fetch() network-level failure that Firefox reports as NetworkError when attempting to fetch resource — same underlying ambiguity, same set of possible causes (CORS, connectivity, mixed content, blocked requests), just different wording depending on which browser's console you're reading.

This error means the fetch() request failed before any HTTP response was received — a fundamentally different situation from an HTTP error status (404, 500), which represents a completed request-response cycle; this error means the request-response cycle never completed at all, for one of several distinct underlying reasons the generic message doesn't itself distinguish.

Why This Error Happens

Browsers deliberately keep fetch()'s network-failure error generic for security reasons, avoiding leaking specifics about why a cross-origin request failed to a potentially malicious script. In practice, the message covers: a CORS policy blocking the response, DNS or connection failures reaching the target server, mixed content blocking (HTTPS page requesting HTTP resource), a browser extension or ad blocker intercepting the request, or the user's actual network connectivity failing.

Reproducing and Diagnosing the Error

The most frequent real-world cause — a CORS-blocking response:

fetch("https://api.example.com/data")
  .then((res) => res.json())
  .catch((err) => console.error(err));
// TypeError: Failed to fetch
// (check the console for a separate, more specific CORS-related log line)

Confirming the request even reaches the server, independent of the browser's CORS enforcement:

curl -I https://api.example.com/data
# If this succeeds but the browser fetch fails, the cause is almost
# certainly CORS, not actual server unavailability

Core Concepts Behind This Error

CORS rejections and genuine network failures produce this identical error message, but Chrome's console typically logs a distinct, more specific line (something like "has been blocked by CORS policy") alongside the generic fetch error — always check the full console output, not just the caught exception object, which rarely carries enough detail on its own to distinguish the cause.

Mixed content (an HTTPS page fetching an HTTP-only URL) is silently blocked by the browser as a security measure, producing this same generic error — the fix is serving the resource over HTTPS, not attempting to work around the block from application code.

Ad blockers and privacy-focused browser extensions can intercept and block specific requests (particularly ones matching known tracking/analytics patterns), producing this exact error for requests that would otherwise succeed — worth testing in an incognito window with extensions disabled specifically when the failure is inconsistent across users or environments.

Actual connectivity failures (DNS resolution failure, connection refused, genuine offline state) also funnel into this same generic message — for these, the request never reached any server at all, distinct from CORS where a response was received but withheld from your script by the browser's own policy enforcement.

Fixing "TypeError: Failed to Fetch"

Fix 1: For CORS-caused failures, fix the server's CORS headers to explicitly allow the requesting origin — this is a server-side configuration fix, not something resolvable from the client:

// Server-side (Express example)
app.use(cors({ origin: "https://yourapp.com", credentials: true }));

Fix 2: For mixed content, ensure every fetched resource uses HTTPS, matching the page's own protocol:

// Wrong: hardcoded HTTP from an HTTPS context
fetch("http://api.example.com/data");
// Fixed
fetch("https://api.example.com/data");

Fix 3: Implement retry logic with backoff for genuine, transient connectivity failures, treating them as expected, recoverable conditions rather than exceptional ones:

async function fetchWithRetry(url: string, attempts = 3): Promise<Response> {
  for (let i = 0; i < attempts; i++) {
    try {
      return await fetch(url);
    } catch (err) {
      if (i === attempts - 1) throw err;
      await new Promise((r) => setTimeout(r, 2 ** i * 500));
    }
  }
  throw new Error("unreachable");
}

How Do You Distinguish CORS From an Actual Network Failure?

Check the browser console for a separate, more specific CORS log line beyond the generic fetch error — both Chrome and Firefox log this distinctly. Then test the same request outside the browser (via curl or an API client not subject to browser CORS enforcement) — if it succeeds there, the cause is CORS; if it also fails there, you're facing a genuine connectivity or server-availability issue instead.

Preventing This Error in Production

Configure CORS explicitly and deliberately for every legitimate origin needing API access, rather than discovering gaps through user-facing errors in production. Build retry-with-backoff handling into your application's fetch utility layer for genuinely transient network conditions, and surface a clear, actionable error state to users distinct from a silent failure, since some rate of network failures is unavoidable at any meaningful scale.

If you hit this error, check the console for a CORS-specific message and test the request outside the browser before assuming general connectivity is the problem — the two causes require entirely different fixes.

Related posts

Written by Suhail Roushan — Full-stack developer. More posts on AI, Next.js, and building products at suhailroushan.com/blog.

Get in touch