How to fix Error: CORS preflight request failed (no 'Access-Control-Allow-Origin') in Node.js

Node.jsINTERMEDIATEHIGHUpdated Dec 9, 2025· 164 views

A CORS preflight request failed because the server didn't respond with the required Access-Control-Allow-Origin header. This happens when your Express server doesn't properly configure CORS headers for complex requests (PUT, DELETE, POST with custom headers).

Quick fix

Fixes Error: CORS preflight request failed (no 'Access-Control-Allow-Origin')

npm install cors
  1. Install the cors package
  2. Apply CORS globally to all routes
  3. Configure CORS for specific origins (production)
  4. Explicitly handle OPTIONS requests if using selective CORS
node.js — error
npm install cors
Error: CORS preflight request failed (no 'Access-Control-Allow-Origin')
shell
npm install cors

What this error means

When browsers make 'complex' HTTP requests (anything other than simple GET/HEAD/POST, or requests with custom headers), they automatically send a preflight OPTIONS request first to check if the server allows the cross-origin request. If your server doesn't respond to this OPTIONS request with the required CORS headers—specifically Access-Control-Allow-Origin—the browser blocks the actual request. This is a browser security feature to prevent unauthorized cross-origin access to your API.

Typical symptoms

  • API requests fail with 'blocked by CORS policy' error in the browser console
  • Preflight OPTIONS requests return 404 or 500 errors
  • The error mentions missing 'Access-Control-Allow-Origin' header
  • Simple requests (GET/HEAD/POST) work fine, but DELETE/PUT/PATCH fail
  • Custom headers like Authorization are causing requests to fail
  • The error appears only when calling API from a different origin (domain/port)

Common causes

  1. The Express server doesn't have CORS middleware installed or configured
  2. CORS middleware is installed but not applied globally with app.use(cors())
  3. OPTIONS requests are not being handled (missing app.options('*', cors()))
  4. CORS is only applied to specific routes, but you're hitting a different route
  5. The allowed origin list doesn't include your frontend's domain
  6. A reverse proxy or load balancer is stripping CORS headers from responses

How to fix "Error: CORS preflight request failed (no 'Access-Control-Allow-Origin')"

1Install the cors package

First, ensure you have the cors middleware installed in your Node.js project:

bash
npm install cors

This is the standard package for handling CORS in Express.

2Apply CORS globally to all routes

Add the CORS middleware to your Express app at the top level, before defining routes:

javascript
const express = require('express');
const cors = require('cors');

const app = express();

// Apply CORS to all routes
app.use(cors());

// Your routes go here
app.get('/api/data', (req, res) => {
  res.json({ message: 'Hello' });
});

app.listen(3000);

This allows requests from any origin. If you only tested with GET requests and they worked, the issue is likely that you're missing CORS headers for complex requests.

3Configure CORS for specific origins (production)

For production, allow only trusted domains:

javascript
const corsOptions = {
  origin: ['https://yourdomain.com', 'https://app.yourdomain.com'],
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  optionsSuccessStatus: 200
};

app.use(cors(corsOptions));

The optionsSuccessStatus: 200 is important for legacy browsers that fail on 204 responses.

4Explicitly handle OPTIONS requests if using selective CORS

If you only want CORS on specific routes, you must explicitly handle OPTIONS:

javascript
app.options('/api/data', cors(corsOptions)); // For specific route
app.post('/api/data', (req, res) => {
  res.json({ message: 'Success' });
});

// Or for all routes
app.options('*', cors(corsOptions));

Without this, preflight OPTIONS requests will return 404 and fail.

5Verify headers in browser DevTools

Check the Network tab in your browser's DevTools:

1. Look for the OPTIONS request that appears before your actual request
2. Click on it and check the Response headers
3. Verify that Access-Control-Allow-Origin is present
4. Verify Access-Control-Allow-Methods includes your HTTP method (POST, DELETE, etc.)
5. If the OPTIONS request returns 404 or 500, your middleware isn't catching it properly

The OPTIONS response should include:
- Access-Control-Allow-Origin: https://yourdomain.com (or *)
- Access-Control-Allow-Methods: GET, POST, PUT, DELETE
- Access-Control-Allow-Headers: Content-Type, Authorization

6Check for middleware ordering issues

Ensure CORS middleware is applied BEFORE route handlers:

javascript
// WRONG - routes defined before cors
app.get('/api/data', handler);
app.use(cors()); // Too late!

// CORRECT - cors applied first
app.use(cors());
app.get('/api/data', handler);

Middleware in Express is executed in order. CORS must be applied before your routes are defined.

Advanced notes

Preflight request behavior: Browsers automatically send OPTIONS preflight requests for 'complex' requests—anything with HTTP methods other than GET/HEAD/POST, or requests with custom headers like Authorization. You cannot disable this from client-side code; it's a browser security feature.

Credentials and wildcard origins: If you use Access-Control-Allow-Credentials: true, you cannot use Access-Control-Allow-Origin: *. You must specify exact origins.

Development vs Production: During development, you might use app.use(cors()) to allow all origins. Always restrict to specific origins in production.

Reverse proxies: If your Express app is behind Nginx or another reverse proxy, the proxy might be stripping CORS headers. Configure the proxy to pass them through.

Custom middleware conflicts: If you have other middleware that sends responses early (like authentication checks), they might bypass CORS headers. Ensure CORS is applied globally before any route-specific middleware.

Frequently asked questions

What does "Error: CORS preflight request failed (no 'Access-Control-Allow-Origin'" mean?
When browsers make 'complex' HTTP requests (anything other than simple GET/HEAD/POST, or requests with custom headers), they automatically send a preflight OPTIONS request first to check if the server allows the cross-origin request. If your server doesn't respond to this OPTIONS request with the required CORS headers—specifically Access-Control-Allow-Origin—the browser blocks the actual request. This is a browser security feature to prevent unauthorized cross-origin access to your API.
How do I fix "Error: CORS preflight request failed (no 'Access-Control-Allow-Origin'"?
A CORS preflight request failed because the server didn't respond with the required Access-Control-Allow-Origin header. This happens when your Express server doesn't properly configure CORS headers for complex requests (PUT, DELETE, POST with custom headers).
What causes "Error: CORS preflight request failed (no 'Access-Control-Allow-Origin'"?
The Express server doesn't have CORS middleware installed or configured CORS middleware is installed but not applied globally with app.use(cors()) OPTIONS requests are not being handled (missing app.options('*', cors()))
Is the "Error: CORS preflight request failed (no 'Access-Control-Allow-Origin'" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading