---
title: CORS Errors Explained (and how to fix them)
description: Every web developer meets the dreaded 'blocked by CORS policy' error. It's not a bug — it's a security feature. Here's what CORS is, why the browser blocks your request, and how to fix it properly.
canonical: https://watchfor.io/blog/cors-errors-explained
---

[All posts](/blog) [Monitoring](/blog/category/monitoring) Mar 02, 2026 · 3 min read · WatchFor Team

# CORS Errors Explained (and how to fix them)

Every web developer meets the dreaded 'blocked by CORS policy' error. It's not a bug — it's a security feature. Here's what CORS is, why the browser blocks your request, and how to fix it properly.

You wire up a frontend to call your API, hit refresh, and the console lights up red: "Access to fetch … has been blocked by CORS policy." Your API works fine in a direct test, so what gives?

The frustrating truth: CORS is working as intended. It's a browser security feature, not a malfunction — and once you understand it, the fix is straightforward.

## What CORS is

CORS (Cross-Origin Resource Sharing) is a browser rule about which sites can call which APIs. By default, browsers enforce the same-origin policy : a page at https://myapp.com can't make JavaScript requests to https://api.other.com unless that other server explicitly allows it .

The key insight: CORS is enforced by the browser , to protect users — not by your server, and not against you. Your API is fine; the browser is refusing to hand the response to JavaScript from a different origin unless the server says it's allowed.

That's why the same request works from a tool like curl (no browser, no CORS) but fails in the browser.

## What counts as a different "origin"

An origin is the combination of scheme + host + port . Any difference makes it cross-origin:

From To Cross-origin?

https://app.com https://api.app.com ✅ Yes (different host)

https://app.com http://app.com ✅ Yes (different scheme)

https://app.com:443 https://app.com:8080 ✅ Yes (different port)

https://app.com/a https://app.com/b ❌ No (same origin)

## How to fix it (the right way)

The fix lives on the server being called — it must send headers permitting the calling origin:

- Send Access-Control-Allow-Origin . Set it to the specific origin that's allowed (e.g. https://myapp.com ), or * for a fully public API.

- Handle the preflight. For many requests the browser first sends an OPTIONS "preflight" asking permission. Your server must answer it with the allowed methods and headers ( Access-Control-Allow-Methods , Access-Control-Allow-Headers ).

- Allow credentials if needed. Sending cookies/auth? Set Access-Control-Allow-Credentials: true — and note you then can't use * for the origin; you must name it.

Header Purpose

Access-Control-Allow-Origin Which origin(s) may read the response

Access-Control-Allow-Methods Which HTTP methods are allowed

Access-Control-Allow-Headers Which custom headers are allowed

Access-Control-Allow-Credentials Whether cookies/auth may be sent

## What not to do

- Don't blindly set Access-Control-Allow-Origin: * on a private/authenticated API. That opens it to every site. Allow only the origins you trust.

- Don't try to "fix" it in the frontend. CORS is server-side policy; a browser can't be told to ignore it (and shouldn't be).

- Don't reach for a proxy as a first resort when the real fix is one header.

## The bottom line

In one line

What A browser rule on cross-origin requests — a security feature.

Why blocked The target server didn't say your origin is allowed.

Fix Send the right Access-Control-Allow-* headers from the server.

Careful Don't use * on private APIs; name trusted origins.

CORS errors feel like the browser fighting you, but it's protecting your users. The fix is almost always a small set of response headers on the API — set them correctly (and narrowly), and the red console messages disappear.

If you build APIs, monitor their headers and responses with the [API monitoring guide](/blog/api-monitoring-guide); inspect any URL's headers with the free [HTTP header checker](/http-header-checker).

[#web](/blog/tag/web)[#debugging](/blog/tag/debugging)[#api](/blog/tag/api)

## Start monitoring your services today

WatchFor checks HTTP, DNS, SSL, ping, email and 20+ more — from around the world, with alerts to Slack, Discord, email and beyond.

[Learn more](/docs/monitors)[Start free](/auth/sign-up)

Share this article

---

Canonical page: https://watchfor.io/blog/cors-errors-explained · Site guide: https://watchfor.io/llms.txt
