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-KeyCommon headers people forget:
Authorization— for JWT tokensX-Requested-With— used by some frameworksContent-Type— even though it seems obvious, some people forget itAccept— 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, OPTIONSIf 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: trueOr serve your local API through HTTPS.
Quick Debugging Checklist#
When you get a CORS error, work through this:
- Open browser DevTools → Network tab
- Find the failed request
- Look for the OPTIONS preflight request (if there is one)
- Check the response headers on the OPTIONS request
- Verify
Access-Control-Allow-Originmatches your frontend origin - Verify
Access-Control-Allow-Methodsincludes your HTTP method - Verify
Access-Control-Allow-Headersincludes your custom headers - If using credentials, verify origin is specific (not
*) andAllow-Credentials: true
Test Your CORS#
After fixing, use headertest.com to verify everything is properly configured.