The 7 CORS Errors You'll See Most (And Exactly How to Fix Each One)

I’ve fixed more CORS errors than I can count. They all look slightly different but most fall into the same handful of categories. Here are the seven you’ll see most often, with the exact fix for each.

Error 1: “No ‘Access-Control-Allow-Origin’ header is present”#

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

This is the most common CORS error. It means your server isn’t sending any CORS headers at all.

The fix: Add CORS headers on the server.

// Express.js
const express = require('express');
const app = express();

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', 'https://myapp.com');
  next();
});
# Nginx
add_header Access-Control-Allow-Origin "https://myapp.com";

Note: this is a server-side fix. Adding CORS headers on the client (React, Vue, etc.) does nothing. I see people try this all the time. It doesn’t work.

Error 2: “credentials mode is ‘include’” but origin is ‘*’#

The value of the 'Access-Control-Allow-Origin' header in the response 
must not be the wildcard '*' when the request's credentials mode is 'include'.

You’re sending cookies or auth headers, but the server is responding with Access-Control-Allow-Origin: *. The browser rejects this combination.

The fix: Use the specific origin, not a wildcard.

app.use((req, res, next) => {
  const allowedOrigins = ['https://myapp.com', 'https://admin.myapp.com'];
  const origin = req.headers.origin;
  
  if (allowedOrigins.includes(origin)) {
    res.header('Access-Control-Allow-Origin', origin);
    res.header('Access-Control-Allow-Credentials', 'true');
  }
  next();
});

Error 3: “Response to preflight request doesn’t pass access control check”#

Response to preflight request doesn't pass access control check: 
Redirect is not allowed for a preflight request.

The preflight (OPTIONS) request is failing. Usually this means the server isn’t handling OPTIONS requests, or it’s redirecting them.

The fix: Handle OPTIONS explicitly.

app.options('*', (req, res) => {
  res.header('Access-Control-Allow-Origin', req.headers.origin);
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.header('Access-Control-Max-Age', '86400');
  res.sendStatus(204);
});

If you’re using the cors npm package, it handles OPTIONS automatically. If you’re setting headers manually, you need to handle it yourself.

Error 4: “is not allowed by Access-Control-Allow-Headers”#

Request header field x-api-key is not allowed by 
Access-Control-Allow-Headers in preflight response.

A custom header in your request isn’t listed in the server’s Access-Control-Allow-Headers.

The fix: Add the header to the allowed list.

Access-Control-Allow-Headers: Content-Type, Authorization, X-API-Key

Common headers people forget:

  • Authorization — for JWT tokens
  • X-Requested-With — used by some frameworks
  • Content-Type — even though it seems obvious, some people forget it
  • Accept — rarely needed, but sometimes

Error 5: “is not allowed by Access-Control-Allow-Methods”#

Method PUT is not allowed by Access-Control-Allow-Methods 
in preflight response.

Your HTTP method isn’t in the allowed list.

The fix: Add the method.

Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS

If you’re using REST APIs, you almost certainly need at least GET, POST, PUT, DELETE.

Error 6: “not allowed by CORS policy” (redirect)#

Access to fetch at 'https://api.example.com/users' from origin 
'https://myapp.com' has been blocked by CORS policy: The request 
was redirected to 'https://other-api.example.com/users'

The server is redirecting the request to a different origin. Preflight requests can’t follow cross-origin redirects.

The fix: Make sure the API responds at the correct URL without redirecting. Common causes:

  • HTTP to HTTPS redirect on the API server (fix by calling the HTTPS URL directly)
  • Trailing slash redirects (/api/users/api/users/)
  • Authentication redirects (API returns 302 to login page)

Error 7: Private Network Access error#

Access to fetch at 'http://192.168.1.100:8080/api' from origin 
'https://myapp.com' has been blocked by CORS policy: The request 
client is not a secure context and the resource is in more-private 
address space.

Chrome’s Private Network Access feature blocks public websites from accessing private network resources (localhost, internal IPs).

The fix: Add the PNA header:

Access-Control-Allow-Private-Network: true

Or serve your local API through HTTPS.

Quick Debugging Checklist#

When you get a CORS error, work through this:

  1. Open browser DevTools → Network tab
  2. Find the failed request
  3. Look for the OPTIONS preflight request (if there is one)
  4. Check the response headers on the OPTIONS request
  5. Verify Access-Control-Allow-Origin matches your frontend origin
  6. Verify Access-Control-Allow-Methods includes your HTTP method
  7. Verify Access-Control-Allow-Headers includes your custom headers
  8. If using credentials, verify origin is specific (not *) and Allow-Credentials: true

Test Your CORS#

After fixing, use headertest.com to verify everything is properly configured.