Guide Errors & Troubleshooting

How to fix a CORS error

The browser blocked the request on purpose, as designed — here is how to tell which side actually needs to grant permission.

Updated 7 min read Advanced

A CORS error appears in the browser console, typically reading close to: "Access to fetch at 'https://api.example.com/data' from origin 'https://yoursite.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource." It means a script on your page tried to make a request to a different origin — a different domain, subdomain, or protocol counts as different — and the browser blocked the response because that other server didn't explicitly say it was permitted.

This is a browser-enforced rule, not a network fault and not a bug in your code in the way a typo would be. The request actually reaches the other server in most cases; the browser is the one refusing to hand the response back to your script, specifically to stop a page from quietly using a visitor's logged-in session against a service it has no business talking to.

What counts as a different origin

Origin is defined strictly: protocol, hostname and port all have to match exactly. https://yoursite.com and http://yoursite.com are different origins. So are yoursite.com and www.yoursite.com. A request that looks like it should obviously be "the same site" to a person can still be cross-origin to a browser.

Work out which server the fix belongs on

This is the single most important step, because the fix always lives on the server being called, never in the page making the request.

1. You control both your site and the API being called

If the request is going to your own API — perhaps on a different subdomain, or over a different protocol than the page itself — the fix is to add a response header on that API server:

Access-Control-Allow-Origin: https://yoursite.com

In Apache, this can be added via .htaccess:

Header set Access-Control-Allow-Origin "https://yoursite.com"

Set the exact origin your site is served from, not a guess at a related one — a mismatch on protocol or subdomain here is one of the most common reasons this still fails after the header has apparently been added.

2. The request first fails with an OPTIONS request in the console

Requests that aren't "simple" by the specification's definition — most that use custom headers, or methods like PUT and DELETE — trigger the browser to send a preflight OPTIONS request first, checking permission before sending the real one. If your server doesn't have a route or handler that responds correctly to OPTIONS for that endpoint, the preflight itself fails and the browser never sends the actual request at all. The fix is making sure the server answers OPTIONS requests for that path with the same Access-Control-Allow-Origin header, plus Access-Control-Allow-Methods and Access-Control-Allow-Headers matching what the real request needs.

3. The API belongs to a third party

If the request is going to a service you don't control, the header has to be added on their end, which means either finding their documentation for allowing your origin — many APIs support this as a configuration option — or contacting them directly. There is nothing to fix on your own server in this case, and no client-side workaround makes it work correctly for every visitor.

Where a third party genuinely doesn't support CORS at all, the usual working pattern is to route the request through your own server instead — your server calls the third-party API directly, server-to-server, where CORS doesn't apply, and your page then calls your own server, which is same-origin.

4. Requests that include cookies or credentials

If the request needs to send cookies or authentication headers, Access-Control-Allow-Origin cannot be set to a wildcard * — the specification blocks that combination deliberately. It must name the exact origin, and the request itself must be sent with credentials: 'include', alongside a matching Access-Control-Allow-Credentials: true header on the response. Missing either half of this pair is a common reason a fix that looks correct still fails specifically for authenticated requests.

A browser extension is not a production fix

Disabling CORS checks in your own browser to get past the error while testing tells you nothing about whether the actual header configuration is correct, and gives every other visitor exactly the same broken experience. Test with the extension off before considering it fixed.

If the header is set and it's still failing

Check the exact response headers using your browser's network tab rather than assuming the server sent what you configured — a caching layer, a CDN, or a second server in front of the application can sometimes strip or override headers before they reach the browser. Send us the exact console message, including the origin and the target URL, and whether the request is going to your own infrastructure or a third party — that distinction determines whether support can help directly or needs to point you at the other service's own configuration.

Frequently asked questions

Can I just fix this from my browser?

No, not for anyone other than yourself. Browser extensions that disable CORS checking only change how your own browser behaves; every other visitor's browser still enforces the policy normally. The header has to be added on the server actually being called, because that is the only place the permission genuinely takes effect for everyone.

Is CORS a security bug in my site?

The opposite — it is a deliberate browser security feature, not a bug. It exists specifically to stop a malicious page on one site from silently making authenticated requests to another site using a visitor's existing session. Seeing the error means the protection is working; the task is configuring it correctly for the cross-origin requests you actually intend.

Related reading