CORS Error Debugger

Walk through exactly why a cross-origin request would be blocked — or confirm it wouldn't be

Blocked by CORS

This request needs a preflight (OPTIONS) first

  • • Method PUT is not a CORS-simple method (only GET, HEAD, and POST avoid a preflight).
  • • Header "X-Custom-Header" is not on the CORS-safelisted header list.
  • • Content-Type "application/json" isn't one of the three simple content types (application/x-www-form-urlencoded, multipart/form-data, text/plain).

Make sure the headers pasted on the left are the preflight (OPTIONS) response, not the actual request's response.

Access-Control-Allow-Origin

Matches the request origin exactly (https://myapp.com).

Access-Control-Allow-Methods

PUT is listed.

Access-Control-Allow-Headers

Not allowed: X-Custom-Header — add them to Access-Control-Allow-Headers on the server.

CORS is enforced entirely by the browser based on what the server's response headers say — there is no fix on the client side. Every fix for a CORS failure happens in the server's configuration (adding or correcting Access-Control-* headers), never in the requesting code.

About this tool

CORS failures are enforced entirely by the browser, based only on what the server's response headers say — there is no client-side fix, ever. This tool walks the exact same decision the browser makes: is this a 'simple' request or does it need a preflight (OPTIONS) first, and do the response headers actually satisfy what's being asked of them? Enter the request's origin, method, custom headers, and whether credentials are included, plus the response headers you actually received, and it checks Access-Control-Allow-Origin (exact match vs. wildcard, and the wildcard-plus-credentials conflict that blocks even a seemingly-correct setup), Access-Control-Allow-Credentials when credentials are involved, and — for requests that need one — whether the preflight response's Access-Control-Allow-Methods and Access-Control-Allow-Headers actually cover what's being requested.

When to use it

  • →Figuring out exactly which Access-Control-* header is missing or wrong when a fetch() call fails with a CORS error
  • →Understanding why a request that worked without credentials breaks once cookies or an Authorization header are added
  • →Checking in advance whether a planned API design (custom headers, non-GET method) will need a CORS preflight
  • →Explaining to a backend team precisely which header to add, instead of just forwarding a vague browser console error

Tips

  • ◆A wildcard Access-Control-Allow-Origin: * is only valid when the request does NOT include credentials — the moment you add cookies or an Authorization header, the server must echo back your exact origin instead, with no exceptions.
  • ◆If your request needs a preflight (any method besides GET/HEAD/POST, or a non-simple header, or a JSON Content-Type), make sure you're pasting the OPTIONS preflight response's headers, not the actual request's response — they can differ.
  • ◆Every fix for a CORS failure happens on the server (adding or correcting an Access-Control-* header) — there is no request configuration, retry logic, or client library setting that works around a server that hasn't opted in.

Frequently asked questions

Why does my request work fine in Postman but fail in the browser?

CORS is a browser-enforced restriction — tools like Postman, curl, and server-to-server requests aren't browsers and don't apply it at all. Working in Postman tells you the server itself responds fine; it tells you nothing about whether the server's CORS headers are configured correctly for a browser.

What counts as a 'simple' request that skips the preflight?

A GET, HEAD, or POST request, using only the CORS-safelisted headers (Accept, Accept-Language, Content-Language, Content-Type), where Content-Type (if set) is one of application/x-www-form-urlencoded, multipart/form-data, or text/plain. Anything else — a custom header, a PUT/DELETE/PATCH method, a JSON Content-Type — triggers a preflight first.

I added Access-Control-Allow-Origin and it still fails — why?

Usually one of: the origin value doesn't exactly match (including the protocol and port, not just the hostname), credentials are involved but Access-Control-Allow-Credentials is missing, or the request needed a preflight and the actual response headers you're checking aren't the preflight's. Run through this tool's checklist in order — it's built to catch exactly these cases.

Related tools

🥷 ToolNinja