GuidesDIAGNOSE
Diagnose and fix a CORS error
A red console message stating that a request has been blocked by CORS policy means the browser withheld the response from your script. The network call often succeeded at the HTTP layer, but the response lacked matching access-control headers. Resolving the issue requires identifying which network phase failed and who controls the server.
Confirm the failure is a CORS error
Browsers log distinct error messages for different network failures. A genuine CORS issue explicitly cites cross-origin resource sharing or states that a request has been blocked by CORS policy. Check the console text before modifying application headers.
- DNS resolution failure or connection refused logs as net::ERR_NAME_NOT_RESOLVED or net::ERR_CONNECTION_REFUSED rather than a CORS fault.
- Mixed content blocks happen when an HTTPS document requests an HTTP asset, logged as a mixed content error before any network traffic is sent.
- Content Security Policy violations log the specific directive such as connect-src that blocked the network call.
- Ad blockers and browser extensions log net::ERR_BLOCKED_BY_CLIENT when matching an internal blocklist rule.
- Typing the wrong URL or protocol scheme triggers immediate network connection errors before the browser checks response headers.
Inspect the Network panel
Open DevTools and locate the failing entry in the Network tab. If the request is not CORS-safelisted, for example because it uses PUT or DELETE, sends a JSON body, or appends custom headers, the browser issues an HTTP OPTIONS preflight request first. A red OPTIONS entry indicates the server failed to validate the preflight call, so the real request never fires. Firefox reports 'CORS failed' in that case.
When the preflight succeeds, or when a request qualifies to skip preflight, the actual request appears in the log. You might see a status code 200 with a full response body visible in DevTools, while your JavaScript catches a TypeError. The browser fetched the payload, examined the headers, discovered no matching permissions, and withheld the body from client code.
Triage the failure
Follow three decision steps to determine where the fix must happen.
- Verify the browser logs
Ensure the console displays a CORS message rather than a generic network disconnect. If the text mentions preflight, review the preflight guide.
- Identify who owns the API
Check whether your team maintains the destination server. If you control the server, configure the necessary response headers directly on your endpoints.
- Determine if the call handles sensitive data
Identify whether the request sends cookies, Authorization headers, or private records. Requests with credentials must go through your own backend, as explained in the proxy-versus-backend comparison.
Knowing who owns the endpoint separates server configuration tasks from client routing architecture.
Common causes of CORS failures
Most console warnings originate from one of five distinct configurations.
- Missing headers. The response lacks
Access-Control-Allow-Originentirely. Chrome logs "No 'Access-Control-Allow-Origin' header is present on the requested resource"; Firefox reports "CORS Missing Allow Origin". Learn how the check works in what CORS checks. - Failed preflight. The server returns an error status on the OPTIONS request, or omits Access-Control-Allow-Methods and Access-Control-Allow-Headers. Diagnose these preflight conditions in the preflight guide.
- Wildcard origin with credentials. The browser forbids reading a response if Access-Control-Allow-Origin is set to * while credentials mode is set to include. The server must return the explicit origin string instead.
- Development proxy mismatch. Requests work locally through a Vite development server proxy, but fail in production because the relative path resolves directly against an unconfigured remote domain. Address this with the Vite recipe.
- Setting
mode: 'no-cors'. The option silences the console error by hiding the response instead: it yields opaque responses with status 0, which breaks JSON parsing in client scripts.
Handle third-party public APIs
Browser JavaScript cannot force an external third-party server to send cross-origin headers. If an external API provider omits Access-Control-Allow-Origin, client-side code running in a browser cannot read the response. You must route the request through an intermediary.
For public, unauthenticated data, you can route GET and HEAD requests through a public proxy like cors.dev. The proxy forwards the upstream request, injects the necessary access headers, and returns the response to your application. Because the proxy operator can observe traffic routed through it, use this approach for public data only.
// Before: fails in the browser if the API sends no CORS headers
const direct = await fetch('https://api.example.com/data');
// After: the proxy re-serves public data with the headers your origin needs
const response = await fetch(
'https://proxy.cors.dev/https://jsonplaceholder.typicode.com/todos/1',
);
const data = await response.json();You can test cross-origin queries against any public HTTPS API in the playground or paste raw upstream headers into the header checker to verify whether an endpoint emits valid access rules.
Protect credentials and private endpoints
Never send sessions, authentication tokens, API secrets, or private personal data through a public CORS proxy. The cors.dev free tier rejects requests carrying cookies or an Authorization header. Managed access supports explicit Authorization and custom API headers, but does not forward browser cookies or hide private credentials embedded in frontend code. When an API requires authentication secrets or handles non-public data, build an endpoint on your own application backend or use the official server SDK to query the remote API securely.
Good questions.
Can I fix a CORS error with JavaScript only?
Modifying client-side fetch options cannot bypass missing server headers. Browsers enforce CORS validation exclusively through HTTP response headers emitted by the target server. Resolving the error requires configuring the destination server directly or routing calls through a proxy server.
Why does the same request work in curl or Postman?
Desktop and command-line HTTP clients do not enforce the same-origin policy. Tools like curl and Postman execute network requests without evaluating cross-origin constraints or issuing preflight checks. Consult the Postman comparison for a detailed walkthrough.
Is a CORS error the server rejecting my request?
The server often accepts and processes the request. When a request requires no preflight, the remote service processes the call and returns an HTTP 200, but the browser hides the body from JavaScript if validation fails. When a non-simple request fails preflight, the browser drops the transaction before sending the application request.
Should I disable browser security to fix it?
Disabling browser security flags affects only your local machine while leaving production users blocked. Running a browser without web security also exposes your authenticated sessions in other tabs to data extraction. Fix the response headers at the server or proxy layer instead.