8 Common CORS Errors in Web Development (and How to Fix Them in Node.js)
Cross-Origin Resource Sharing (CORS) errors are among the most frequent and frustrating issues in modern web development. These errors stem from strict browser security policies that restrict how resources on a web page can be requested from another domain. While this security mechanism is essential for protecting users from malicious attacks, it often complicates communication between client-side applications and backend APIs. This expanded guide explores the eight most common CORS error types, their root causes, real-world problems that developers face, and best-practice solutions, especially in Node.js/Express environments.
1. Missing Access-Control-Allow-Origin Header
Real-World Problem
A startup deploying its frontend on Vercel and backend on Heroku finds that all API calls fail with CORS errors.
Cause
This occurs when the server doesn’t include the Access-Control-Allow-Origin
header in its responses, causing the browser to block the request.
Solution
Use the cors
package in Express or manually set the headers.
app.use(
cors({ origin: "http://client-app.com" })
);
2. Preflight Request Failure (OPTIONS Method)
Real-World Problem
A SaaS platform integrates file uploads, triggering PUT requests with custom headers. These fail silently.
Cause
Browsers issue an OPTIONS request (preflight) for non-simple HTTP requests. If the server doesn’t handle it properly, the browser blocks the actual request.
Solution
Explicitly handle the OPTIONS method in Express.
app.options("/upload", cors());
3. Multiple Origin Values in Header
Real-World Problem
An app uses both Nginx and Node.js CORS middleware. Users report inconsistent access issues.
Cause
Multiple layers may inject duplicate CORS headers.
Solution
Ensure CORS headers are set only once.
curl -I http://api.example.com/data
4. Credentialed Requests with Wildcard Origin
Real-World Problem
A dashboard app using cookies with withCredentials: true
fails due to wildcard origin configuration.
Cause
Wildcard *
is not allowed with credentialed requests.
Solution
Specify exact origins and allow credentials.
cors({ origin: whitelist, credentials: true });
5. Origin/Protocol Mismatch
Real-World Problem
Frontend hosted on https://
but backend runs on http://localhost
, causing a mismatch.
Cause
Exact match including protocol, domain, and port is required.
Solution
Add all variants to your origin list:
const allowedOrigins = ["https://client-app.com", "http://localhost:3000"];
6. Invalid SSL/TLS Configuration
Real-World Problem
API hosted on a subdomain with a self-signed certificate fails all requests.
Cause
Browsers reject responses from endpoints with invalid or untrusted SSL certificates.
Solution
Use trusted CA certificates and ensure the HTTPS setup is correct.
7. Disallowed HTTP Methods
Real-World Problem
Requests using PATCH or DELETE get blocked by the browser.
Cause
The server must explicitly allow these methods in Access-Control-Allow-Methods
.
Solution
Configure allowed methods correctly:
cors({ methods: ["GET", "POST", "PATCH", "DELETE"] });
8. Unauthorized Request Headers
Real-World Problem
An app sends custom headers like X-Token
and X-Client
, which are blocked.
Cause
Only listed headers are allowed in cross-origin requests.
Solution
Add them to Access-Control-Allow-Headers
.
cors({ allowedHeaders: ["Content-Type", "X-Token"] });
Final Thoughts
CORS can be complex, but understanding how the browser enforces it and how to configure the server correctly helps prevent disruptions in development and production. By following the solutions outlined here and testing configurations thoroughly, developers can build secure and seamless integrations between frontend and backend services.
Top comments (0)