Why Is an OPTIONS Request Sent? (CORS Preflight Explained)

Reynaldi
Reynaldi •

In this article, you will learn why your browser sends an OPTIONS request before your actual API call, what triggers it, and how to fix it when it fails.

What Is an OPTIONS Request?

Your browser sends an OPTIONS request to ask the server: “Is this cross-origin request allowed?”

This is also called a preflight request — it’s part of the CORS (Cross-Origin Resource Sharing) mechanism. Before making the actual GET, POST, PUT, or DELETE call, the browser sends this lightweight check first.

The server responds with CORS headers that say which origins, methods, and headers are permitted. If the response is valid, the browser follows up with the real request. If not, it blocks the request entirely — and you see a CORS error in your console.

You cannot disable this from the frontend. It’s browser behavior, not something in your code.

What Triggers a Preflight Request

Not every cross-origin request triggers a preflight. The browser only sends one for “non-simple” requests — requests that go beyond what an HTML form could do natively.

A request is considered “simple” (no preflight) if all of these are true:

  • Method is GET, HEAD, or POST
  • No custom headers (only CORS-safelisted headers like Accept, Content-Language, Content-Type)
  • Content-Type is one of: application/x-www-form-urlencoded, multipart/form-data, or text/plain

The moment you break any of these rules, the browser sends a preflight. The most common triggers:

  • Setting Content-Type: application/json (almost every modern API call)
  • Adding an Authorization header
  • Using PUT, PATCH, or DELETE methods

In practice, almost every API call from a frontend app triggers a preflight.

What a Preflight Request Looks Like

The browser sends something like this:

OPTIONS /api/users HTTP/1.1
Host: api.example.com
Origin: https://myapp.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization

The server should respond with:

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

That tells the browser: “Yes, https://myapp.com is allowed to make a POST with those headers.” The browser then proceeds with the actual request.

If the server returns a 405 Method Not Allowed, no CORS headers, or the wrong values — the browser kills the request before it even fires.

Can You Avoid Preflight Requests?

Sometimes, yes. If you can keep your requests “simple” (as defined above), the browser won’t send a preflight. That means using POST with Content-Type: text/plain and no custom headers.

But that’s usually impractical. You’d be warping your API design just to avoid an extra round trip.

A better approach: cache preflight responses. The Access-Control-Max-Age header tells the browser to remember the preflight result so it doesn’t ask again for a given endpoint. Set it to 86400 (24 hours) and most repeat requests skip the preflight entirely.

Why Your OPTIONS Request Is Failing

If your preflight is failing, the server either doesn’t handle OPTIONS at all (returns 404 or 405), is missing the required CORS headers, or the header values don’t match what your request actually sends.

If you control the server, configure CORS properly. If you don’t control the server, use Corsfix to fix the preflight error. Corsfix acts as a proxy — your request goes through a server that adds the correct CORS headers before returning the response to your browser.

// ❌ Direct call fails with preflight error
fetch("https://api.example.com/data");
// ✅ Corsfix handles CORS for you
fetch("https://proxy.corsfix.com/?https://api.example.com/data");

For local development, this works instantly without registration. For live websites, set up your domain (takes 30 seconds).

Conclusion

The browser sends an OPTIONS request as a preflight to check if a cross-origin request is allowed. Your server must respond with the correct Access-Control-Allow-* headers, or the browser blocks the real request. If you don’t control the server, use Corsfix to handle CORS for you. It’s free to get started, and you only need to upgrade when you go to production.

It's time to build great websites without CORS errors

Try our CORS proxy for free, all features included.

Fix CORS errorsNo credit card required.