DEV Community

Cover image for How to fix CORS errors in Node.js
Asad Bukhari
Asad Bukhari

Posted on

How to fix CORS errors in Node.js

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" })
);
Enter fullscreen mode Exit fullscreen mode

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());
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 });
Enter fullscreen mode Exit fullscreen mode

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"];
Enter fullscreen mode Exit fullscreen mode

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"] });
Enter fullscreen mode Exit fullscreen mode

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"] });
Enter fullscreen mode Exit fullscreen mode

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)