Blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present
"Blocked by CORS policy" on your live site? The server you call must allow your domain. How to fix it for APIs you own and ones you don't.
Reviewed October 14, 2026
What it means in plain English
Browsers stop a web page from reading responses from another website unless that website says "this domain is allowed". That permission is the Access-Control-Allow-Origin header. Locally it may have worked because your origin was localhost.
Likely causes
- Your API/server allows
localhostbut not your production domain. - The API never sends CORS headers (common for third-party APIs not meant to be called from browsers).
- The preflight
OPTIONSrequest isn't handled (see the Supabase Edge Function page). - A server crash returns an error page without CORS headers, so a 500 shows up as a CORS error.
How to fix it, step by step
- Open DevTools → Console/Network and note which URL is blocked.
- If you control that server: add your live origin, e.g.
Access-Control-Allow-Origin: https://yourapp.com. Use*only for truly public APIs; it doesn't work with cookies/credentials. If you need several domains, echo back the request'sOriginwhen it's on your allow list and addVary: Origin. - If you don't control it: call it from your own backend instead of the browser (a Next.js route handler, Vercel/Netlify function or Supabase Edge Function), or proxy it. Netlify example in
_redirects:/api/* https://api.example.com/:splat 200. - Keep API secret keys in that backend, not the browser.
- Check server logs for crashes: fix the 500 and the 'CORS' error often disappears.
How to check it worked
- Reload; the Network request should succeed and the response include
Access-Control-Allow-Origin. - Test from the live domain, not just localhost.
Sources
Related fixes
Can't fix it? Get help.
If the steps didn't clear the error, send what the screen says. A person can take a look. This is a request for a paid fix, not an instant chat.