glimfly
web updated

What is CORS and why is it blocking your app?

In one sentence:CORS is the browser's rule that blocks your frontend's JavaScript from reading a response from a different origin unless the server explicitly says it's allowed.

What it actually is

CORS stands for Cross-Origin Resource Sharing. It’s a rule your browser enforces: JavaScript running on one origin (a specific combination of protocol, domain, and port) can’t read the response from a different origin’s API unless that API explicitly says it’s welcome to.

Think of it like a bouncer at a door. Your frontend, say JavaScript running at localhost:3000, tries to fetch data from your backend at localhost:8000 (different port, so a different origin). The bouncer at localhost:8000 checks whether localhost:3000 is on the guest list. If the server doesn’t send back the right header (Access-Control-Allow-Origin), the browser throws the response in the trash before your code ever sees it, even if the server processed the request just fine. That’s the part that trips people up: CORS is a browser-side block, not a server-side rejection. A plain GET request still reaches your server and gets processed. Your JavaScript just can’t read the response. Requests that need a preflight check work differently: if the preflight fails, the browser never sends the real request, so your server doesn’t see it either.

Why your AI just did this

Your agent adds or trips over CORS whenever a frontend and backend live on different origins. That’s most projects: a React app on localhost:3000 calling an Express or FastAPI server on localhost:8000 during local dev, or a deployed frontend on your-app.vercel.app calling an API on your-api.onrender.com. To make that work, the agent needs the backend to send Access-Control-Allow-Origin headers naming the frontend’s origin, typically through a library like Express’s cors middleware rather than hand-written headers.

It also comes up when you ask your AI to call a third-party API directly from browser code. Some APIs allow that (they set permissive CORS headers); many don’t, because they expect you to call them from your own backend, not from a stranger’s browser tab.

When you’ll run into it

The classic sighting is a red line in your browser’s dev console (F12 → Console tab):

Access to fetch at 'http://localhost:8000/api/users' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Or the preflight version: Response to preflight request doesn't pass access control check. That means your browser sent a heads-up OPTIONS request before the real one, and the server never answered it correctly.

It also shows up as “this worked in Postman/curl but not in my app,” which is real and expected, because Postman and curl aren’t browsers and don’t enforce CORS at all. And it tends to appear right after deployment, when a project that worked fine on localhost suddenly spans two different real domains.

What to check

  • Read the exact origin named in the error message and confirm it’s on the backend’s allowed-origins list, character for character (including http vs https)
  • Avoid Access-Control-Allow-Origin: * on any endpoint that uses cookies or auth headers. Browsers reject that combination outright, and it’s a weak default for anything beyond a public read-only API
  • Open the Network tab and check whether the failing request is the actual call or the OPTIONS preflight. They’re configured differently
  • If you’re using cookies for login, make sure the frontend sends credentials: 'include' and the backend sends Access-Control-Allow-Credentials: true with a specific (non-wildcard) origin
  • Before shipping, replace any wildcard or “allow everything” CORS config from local dev with a list of your real production domains

Say it like a dev

Instead of: “the API doesn’t work from my app, but it works in Postman” Say: “I’m getting a CORS error in the browser console when my frontend calls my backend. Can you add CORS headers allowing my frontend’s origin?”

Instead of: “the network request is broken” Say: “This looks like a CORS preflight failure on the OPTIONS request. Can you check the allowed origins and methods on the server?”

Instead of: “just add a wildcard so it stops complaining” Say: “Add CORS headers, but restrict them to my actual frontend origin, not a wildcard, since we’re sending cookies for auth”

People actually ask

“What is CORS and why is it so annoying?”

CORS is a browser security rule that blocks your frontend JavaScript from reading a response from a different origin (domain, port, or protocol) unless the server explicitly allows it. It's annoying because it's one of the few errors that shows up only in the browser, not in tools like Postman or curl, so it feels like your code is broken when really it's a missing header on the server.

“I hate CORS so much, why does everyone say that?”

Because the fix isn't in the code that's throwing the error. The browser console points at your fetch call, but the actual problem, and the actual fix, lives on the server, in headers you may not have written yourself. It also tends to appear right after you think a feature is done, like right after deploying to two different domains.

“Is a CORS error a bug in my code?”

Not in your fetch call, no. It means the server you're calling hasn't opted in to allow requests from your frontend's origin. The fix is adding the right Access-Control-Allow-Origin header on the backend, not changing how the frontend makes the request.

Related terms

Glim can explain your sessions, live.

The app watches your coding agent and narrates it in plain words. Waitlist is open.

Join the waitlist