CORS Error

Browser Security - Cross-origin request blocked

CORS Errors Explained

What is CORS?

CORS (Cross-Origin Resource Sharing) is a browser security feature that restricts web pages from making requests to a different domain than the one serving the page. When blocked, you'll see an error like:

Access to fetch at 'https://api.example.com/data' from origin
'https://myapp.com' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present.

Why Does This Happen?

Same-Origin Policy

Browsers block requests where origin (protocol + domain + port) differs between the page and the API. This prevents malicious sites from stealing data.

  • https://app.comhttps://api.com Blocked
  • http://app.comhttps://app.com Blocked (different protocol)
  • https://app.com:3000https://app.com:8080 Blocked (different port)

Common CORS Errors

Missing Access-Control-Allow-Origin

Server doesn't include the required CORS header in response.

Preflight Request Failed

OPTIONS request returned an error or wrong headers.

Credentials Not Supported

Trying to send cookies but server doesn't allow credentials.

Server-Side Fixes

Express.js

const cors = require('cors');

// Allow all origins (development only!)
app.use(cors());

// Production: specific origins
app.use(cors({
  origin: ['https://myapp.com', 'https://www.myapp.com'],
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE']
}));

Nginx

location /api/ {
    add_header 'Access-Control-Allow-Origin' 'https://myapp.com';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';

    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Max-Age' 86400;
        return 204;
    }
}

Django

# settings.py
INSTALLED_APPS = [..., 'corsheaders']
MIDDLEWARE = ['corsheaders.middleware.CorsMiddleware', ...]

CORS_ALLOWED_ORIGINS = [
    'https://myapp.com',
]
CORS_ALLOW_CREDENTIALS = True

Required Headers

Header Purpose
Access-Control-Allow-Origin Which origins can access
Access-Control-Allow-Methods Allowed HTTP methods
Access-Control-Allow-Headers Allowed request headers
Access-Control-Allow-Credentials Allow cookies/auth headers

Preflight Requests

For non-simple requests (custom headers, PUT/DELETE methods), browsers send an OPTIONS request first:

# Browser sends preflight
OPTIONS /api/users HTTP/1.1
Origin: https://myapp.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization

# Server must respond with:
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://myapp.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Authorization

Common Mistakes

  • Using * with credentials: Can't use wildcard origin with cookies
  • Missing OPTIONS handler: Preflight returns 404 or 405
  • Headers not exposed: Custom response headers need Access-Control-Expose-Headers
  • Caching issues: Browser cached old CORS response

Debugging Tips

  • Check the Network tab for the actual response headers
  • Look for the preflight OPTIONS request
  • Test with curl (bypasses CORS): curl -I https://api.example.com
  • Server-side errors may also cause CORS to fail (fix the 500 first)

How to Monitor for CORS Issues

CORS errors are client-side but often stem from server misconfigurations. UptimeSignal monitors your API endpoints to ensure they're responding correctly. If your API returns a 500 error, the browser may show a CORS error instead of the actual server error. Monitor your API health to catch the root cause.

Frequently Asked Questions

What is a CORS error?
CORS (Cross-Origin Resource Sharing) errors occur when a browser blocks a request from one domain to a different domain because the server didn't include the required Access-Control-Allow-Origin header. It's a browser security feature (Same-Origin Policy) that prevents malicious sites from making requests to your API on behalf of users.
How do I fix CORS errors?
Add Access-Control-Allow-Origin to your server response. For a specific domain: set it to https://yourfrontend.com. For all origins: use * (not recommended for authenticated APIs). In Express.js use the cors() middleware. Also handle preflight OPTIONS requests.
What is a CORS preflight request?
A preflight is an OPTIONS request the browser sends before non-simple requests (PUT, DELETE, custom headers, JSON content-type) to check if the server allows it. Your server must respond to OPTIONS with Access-Control-Allow-Methods, Access-Control-Allow-Headers, and Access-Control-Allow-Origin headers. Return 204 No Content for OPTIONS.
Why do CORS errors only happen in browsers?
CORS is enforced by browsers, not servers. Server-to-server requests (curl, Postman, backend code) bypass CORS entirely because there's no browser security context to protect. This is why your API works in Postman but fails from JavaScript. The Same-Origin Policy exists to protect users from malicious websites.
How do I allow credentials with CORS?
Set Access-Control-Allow-Credentials: true and specify the exact origin (not *). In fetch: use credentials: 'include'. The wildcard * is not allowed with credentials -- you must echo back the specific requesting origin.

Monitor your API endpoints for errors

UptimeSignal checks your endpoints from outside your network and catches errors before users do.

25 monitors free, unlimited for $15/month.

Related Errors & Resources