Skip to content

Fix CORS Preflight OPTIONS Request Blocked

DodaTech Updated 2026-06-26 2 min read

In this tutorial, you'll learn about Fix CORS Preflight OPTIONS Request Blocked. We cover key concepts, practical examples, and best practices.

Browsers send an OPTIONS preflight request before cross-origin POST, PUT, DELETE, or requests with custom headers. If the server does not handle OPTIONS correctly, the browser blocks the actual request and shows a CORS error in the console.

Wrong

The server only defines routes for GET and POST but omits an OPTIONS handler. When the browser sends the preflight, it receives no CORS headers.

const express = require('express');
const app = express();

app.post('/api/data', (req, res) => {
  res.json({ ok: true });
});

app.listen(3000);
Access to fetch at 'https://api.example.com/api/data' from origin
'https://app.example.com' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource.

Handle the OPTIONS method explicitly or use the cors middleware which handles preflights automatically.

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

app.use(cors({
  origin: 'https://app.example.com',
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
}));

app.post('/api/data', (req, res) => {
  res.json({ ok: true });
});

app.listen(3000);

The middleware intercepts the OPTIONS request and returns:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400

If you must write the handler manually:

app.options('*', (req, res) => {
  res.setHeader('Access-Control-Allow-Origin', 'https://app.example.com');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.setHeader('Access-Control-Max-Age', '86400');
  res.sendStatus(204);
});

Prevention

  • Use the cors npm package instead of writing manual CORS handling in Express.js.
  • Always include OPTIONS in the allowed methods list.
  • Register the CORS middleware before all route definitions so preflights are caught first.
  • Set Access-Control-Max-Age to cache preflight responses and reduce request overhead.
  • Validate that the Origin header matches an allowed list before echoing it back.
  • Test preflight behavior with curl -X OPTIONS -H "Origin: https://app.example.com" -H "Access-Control-Request-Method: POST" https://api.example.com/api/data.

DodaTech Tools

Doda Browser enforces strict CORS policies and surfaces preflight failures in its developer network panel. DodaZIP archives API configuration snapshots including CORS rules for compliance audits. Durga Antivirus Pro uses CORS preflights to verify the integrity of its cloud-based threat intelligence endpoints.

FAQ

### What triggers a CORS preflight request?

A preflight (OPTIONS) is triggered for non-simple requests: methods other than GET/HEAD/POST, custom headers like Authorization or X-Custom-Header, or content types other than application/x-www-form-urlencoded, multipart/form-data, or text/plain. Cookies or credentials do not trigger a preflight alone.

What is the difference between simple and preflight requests?

Simple requests use GET, HEAD, or POST with only simple headers and standard content types. The browser sends them directly without a preflight. All other requests trigger an OPTIONS preflight. The server must respond to the preflight before the browser sends the actual request.

How do I debug a failed preflight request?

Open browser DevTools to the Network tab, filter by OPTIONS, click the preflight request, and check the response headers. The Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers headers must be present and match the actual request's requirements. Use curl to reproduce: curl -X OPTIONS -H "Origin: https://yourdomain.com" -H "Access-Control-Request-Method: POST" -v https://api.yourdomain.com/endpoint.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro