← All Tools

CORS Error vs. Network Error: Why Browsers Won't Tell You Which

Guide · Last verified Aug 26, 2026

You've probably called an API from the browser and gotten nothing but "request failed," with no way to tell what actually went wrong. Was a header missing on the server? Or was the server just down? The code alone can't tell you. This isn't a mistake developers keep making — it's because the browser's fetch() API is deliberately designed to withhold that information. This guide covers why it's designed that way, and what you actually need to look at to figure out the real cause.

1. Two very different failures, lumped into one TypeError

When a fetch() request fails to get a response at all, there are broadly two possible causes. One is a CORS policy violation, where the browser blocks the response from ever reaching your JavaScript. The other is a pure network failure — the server is down, DNS resolution failed, the connection never got established in the first place. The causes are completely different, but fetch() throws the exact same exception either way: TypeError: Failed to fetch. No matter how closely you inspect error.message inside your catch block, there's no clue as to which one it was.

2. Why the browser deliberately hides the reason

This isn't a bug — it's a security decision. If fetch told your JavaScript the difference between "blocked because CORS headers were missing" and "the server never responded," a malicious script could use that distinction to probe an internal network the user is logged into: does a server actually exist there and respond (but get blocked by CORS), or does it not exist at all (a network error)? To prevent that kind of information leak, the spec itself requires both failure modes to be surfaced as the same opaque error. It's inconvenient for developers, but it's a deliberate tradeoff made to avoid handing attackers useful information.

3. The code alone won't answer it — checking DevTools instead

Since the exception object thrown by fetch() carries no distinguishing information, finding the actual cause means opening your browser's developer tools directly. The Network tab shows whether the request reached the server at all (whether a response status code shows up) or failed outright while still pending. The Console tab is where the browser logs a separate warning on a CORS violation (something like "has been blocked by CORS policy") — a message that JavaScript code can't read programmatically, and that only a human looking at the console can see.

Where to checkIf blocked by CORSIf it's a pure network error
Network tab statusRequest reaches the server, response comes back (status code is visible)The request itself fails (shown as pending/failed)
Console logWarning shown: "blocked by CORS policy"No CORS-related log
What catch(e) sees in JSTypeError: Failed to fetchTypeError: Failed to fetch (identical)

4. How MODOO HUB's API Tester handles this

Looking at the actual request-handling code in the API Tester, it's implemented like this:

Actual code logic: catch(e){ if(e.name==='TypeError'){ /* show a message covering a CORS block or a network error */ } }
In other words, this tool openly acknowledges the browser's limitation — that e.name alone can't distinguish CORS from a network error — and shows a message covering both possibilities at once: "This may have been blocked by CORS policy, or it could be a typo'd URL, a down server, or a network connection issue." Not committing to a single cause is itself the correct design here.

5. A checklist for narrowing down the real cause

Frequently Asked Questions

Q. Are there other exception names besides TypeError I might see?

A. Yes. If the URL itself is malformed, a different error can occur right at the fetch call. And if the request reaches the server and gets back a response code (404, 500, etc.), that's not treated as an exception at all — it's a normal response. The TypeError-for-both-CORS-and-network-errors behavior only applies when the request itself fails outright.

Q. Can a CORS problem be fixed from the client side?

A. No. Whether CORS is allowed can only be resolved by the server setting the right response header (Access-Control-Allow-Origin). The only client-side workaround is to route the call through your own server as a proxy, making it a server-to-server request instead.

Q. Does calling an HTTP API from an HTTPS page trigger the same error?

A. Yes. A Mixed Content policy violation also gets blocked by the browser outright, and from JavaScript's point of view it looks like the exact same TypeError as a CORS or network error. You can tell it apart by checking whether the Console tab shows a "Mixed Content" warning.

Q. Can the MODOO HUB API Tester confirm for certain whether it's CORS?

A. No. This tool uses the browser's fetch as-is, so it has the same limitation. It only shows both possibilities together — confirming which one it actually is requires checking the Network/Console tabs yourself, or reproducing the request with a tool like curl outside the browser.