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.
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.
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.
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
Your page is secure but one thing on it is not, and the browser is refusing to pretend otherwise — here is how to find that one thing.
How to call an external API from PHPcURL, an authentication header and a decoded JSON response — the three parts of calling any external API from a PHP script.
How to add security headers to your siteA handful of response headers close off entire categories of attack for very little effort. Here is what each does and how to add them.
How to fix "Error establishing a database connection"A blank page with one line of text, and five possible causes. Here is how to tell which one you have, in the order worth checking.