Deploy Error Decoder

'Blocked by CORS policy' — what it is and how to fix it

Quick answer: A CORS error (blocked by CORS policy: No 'Access-Control-Allow-Origin' header) is the browser refusing a cross-origin response because your server didn't say the origin is allowed. It's fixed on the server, not the client: send the Access-Control-Allow-Origin header and, for non-simple requests, answer the preflight OPTIONS call. Never "fix" it by disabling browser security.

What the error looks like

It appears only in the browser console — the network request often succeeds, the browser just hides the response:

Access to fetch at 'https://api.example.com/data' from origin
'https://app.example.com' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the
requested resource.

Key insight: CORS is enforced by the browser, not the server. The server happily responded; the browser refused to hand the response to your JavaScript because the permission header was missing.

Why it happens

The server doesn't send the header

No Access-Control-Allow-Origin on the response, so the browser blocks it.

The preflight isn't handled

Non-simple requests send an OPTIONS preflight first; if the server doesn't answer it correctly, the real request never happens.

Credentials + wildcard clash

With credentials: 'include' you cannot use * — you must echo the specific origin and send Allow-Credentials: true.

Origin mismatch

http vs https, a trailing slash, or a different port makes it a different origin than the one allowed.

Diagnose it in three steps

1

Is it the preflight or the request?

# Network tab: an OPTIONS request that fails -> preflight problem.
# OPTIONS ok but GET/POST blocked -> missing header on the real response.
2

Check the actual response headers

curl -I -H "Origin: https://app.example.com" https://api.example.com/data
# Look for Access-Control-Allow-Origin in the response.
3

Fix it on the server

const cors = require('cors');
app.use(cors({
  origin: 'https://app.example.com',   // not '*' if using credentials
  credentials: true,
}));   // this also answers the OPTIONS preflight
The real fix

Allow the origin on the server — never disable the browser

The only correct fix is server-side: explicitly allow the calling origin, handle the preflight, and match the credentials rules. Disabling web security in the browser or a hacky proxy is not a fix — it hides the problem and ships a vulnerability.

# If you can't change the API, route same-origin through your own
# backend or reverse proxy and add the header there — under your control.
How Infraveil handles this

Consistent headers and policy at the gateway

CORS is your application's header to set — Infraveil won't paper over a missing one. But its gateway runs in front of your services on your own servers, which is a natural place to apply consistent headers and access policy across everything you run, instead of configuring it differently in every service.

A gateway in front of your services where headers and policy live in one place
Security rules applied without changing application code
Every policy change recorded, on servers you control

Frequently asked questions

What does 'blocked by CORS policy' mean?

The browser blocked your JavaScript from reading a cross-origin response because the server didn't include an Access-Control-Allow-Origin header permitting your origin.

Is CORS fixed on the client or the server?

The server. The browser enforces CORS, but the permission comes from response headers the server sends. You cannot fix it from client JavaScript.

What is a CORS preflight?

For non-simple requests, the browser first sends an OPTIONS request asking whether the real request is allowed. The server must answer it with the right Allow headers before the real request proceeds.

Why can't I use Access-Control-Allow-Origin: * with credentials?

The spec forbids the wildcard when credentials are included. You must echo the specific requesting origin and also send Access-Control-Allow-Credentials: true.