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();
});
```text

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.

```javascript
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);
});
```text

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](https://headertest.com) to verify everything is properly configured.