CORS Checker

Find out why a browser blocks a cross-origin request: whether it needs a preflight, which header the preflight or response is missing, and which headers your JavaScript can read — step by step, by the Fetch standard.

CORS Checker

Nothing open
On this device

The request

What the server answered

Why is the browser blocking my request?

Enter the page’s origin and the URL it calls, then paste the response headers from the Network tab. Each step the browser takes is checked in order; the first that fails is the reason.

Follows the Fetch standard: preflight, the CORS check, credentials and readable headers

How is this calculated?
The rules are the Fetch standard’s: CORS-safelisted methods and request headers (with their value limits and the 1,024-byte total), the CORS check (exact origin match; * never with credentials; Access-Control-Allow-Credentials must be exactly true), the preflight checks (a 2xx status; Access-Control-Allow-Methods and -Headers, where * is a wildcard only without credentials and never covers Authorization), and the CORS-safelisted response headers. Methods other than DELETE, GET, HEAD, OPTIONS, POST and PUT are not upper-cased, so fetch with method "patch" sends "patch".

Runs in your browser — nothing you enter leaves this device.

About this tool

What it does

Explains a CORS error by walking through what the browser does, in the order the Fetch standard sets out. Is the request cross-origin at all? Does it need a preflight — is the method something other than GET, HEAD or POST, or does the script set a header that is not on the safelist (a Content-Type of application/json is the usual one)? If there is a preflight, did it succeed with a 2xx status, does Access-Control-Allow-Origin match exactly, are credentials allowed, is the method allowed, is every header allowed? Then the same origin check on the real response, and finally which response headers your JavaScript may read. The first step that fails is the reason for the error in the console.

How to use it
  1. Enter the page’s origin (where the script runs) and the URL it requests, the method, and the fetch credentials mode.
  2. List the headers the script sets, one per line.
  3. From the Network tab, paste the OPTIONS request’s response headers (if there is one) and the real response’s headers.
  4. Read the steps; the failing one says what the server must send.
Limits and your data
  • It checks headers you paste, not a live server; a CDN or proxy may answer differently from what you copied.
  • Private Network Access (a public page calling a local address) has extra rules that are not covered.
  • Whether cookies are actually sent also depends on SameSite and on the browser’s third-party cookie settings.
  • Everything is checked in your browser; nothing is sent, and the page works offline. Remove tokens from pasted headers before sharing a screenshot.

Questions

The request reached my server, so why does the browser say CORS error?

CORS protects reading the response, not sending the request. A simple request is sent and processed; the browser then hides the response from the page because the CORS check failed. That is also why CORS is not CSRF protection.

Why does my preflight return 401?

Browsers never send cookies or an Authorization header on a preflight, so an OPTIONS route behind authentication fails. Let OPTIONS through without authentication.

Access-Control-Allow-Headers is *, so why is Authorization refused?

The standard excludes Authorization from the wildcard. List it by name: Access-Control-Allow-Headers: Authorization, Content-Type.

Can I allow several origins?

Access-Control-Allow-Origin holds exactly one origin. Check the request’s Origin against your list on the server, echo it back when it matches, and send Vary: Origin.