A CORS preflight request is the browser asking a server for permission before sending certain cross-origin requests.
Backend developers usually notice preflights when an API works in Postman but fails in the browser, or when frontend requests suddenly trigger OPTIONS calls.
Quick answer
A CORS preflight is an OPTIONS request sent by the browser before the real request. It checks whether the target server allows the calling origin, HTTP method, request headers, and credential mode.
If the preflight response is missing the required CORS headers, the browser blocks the real request from frontend JavaScript.
Preflight is not authentication. It is a browser access-control check for cross-origin reads and writes. Your API still needs normal authentication, authorization, validation, and abuse controls.
When browsers send preflight
Browsers send a preflight when a cross-origin request is not considered a simple request.
Common triggers include:
- Methods such as
PUT,PATCH, orDELETE. - Request headers such as
Authorization. - JSON requests with
Content-Type: application/json. - Custom headers like
X-Request-IDorIdempotency-Key. - Credentialed cross-origin requests in many practical setups.
Example browser flow:
OPTIONS /api/orders
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization, content-type, idempotency-key
The server is expected to answer whether that origin, method, and header set is allowed.
Required response headers
A typical preflight response looks like this:
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PATCH, DELETE
Access-Control-Allow-Headers: authorization, content-type, idempotency-key
Access-Control-Max-Age: 600
The key headers are:
| Header | Meaning |
|---|---|
Access-Control-Allow-Origin | Which origin may read the response. |
Access-Control-Allow-Methods | Which HTTP methods are allowed. |
Access-Control-Allow-Headers | Which non-simple request headers are allowed. |
Access-Control-Allow-Credentials | Whether credentialed requests are allowed. |
Access-Control-Max-Age | How long the browser may cache the preflight result. |
The response body usually does not matter. Many APIs return 204 No Content.
Credentials and cookies
Credentialed browser requests add more rules.
If the frontend sends cookies or uses credentials: "include", the server must usually return:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://app.example.com
Do not combine credentialed requests with Access-Control-Allow-Origin: *. Browsers reject that combination.
Cookie-based authentication also needs secure cookie attributes. Read SameSite Cookies Explained, Cookie vs Token Authentication, and Cookie Security Checklist before relying on cross-origin cookies.
Handling OPTIONS in the backend
Many CORS bugs happen because the application never routes OPTIONS requests correctly.
A backend should handle preflight before normal endpoint logic blocks the request. In many frameworks, this belongs in middleware, a gateway, or an edge rule.
Good behavior includes:
- Return CORS headers for allowed origins.
- Return allowed methods and headers that match the real API.
- Avoid requiring user authentication for the preflight itself.
- Keep the origin allowlist explicit.
- Return a clear status such as
204or200. - Avoid expensive database calls for preflight.
The real request still needs authentication. The preflight only answers whether the browser is allowed to proceed.
Preflight caching
Access-Control-Max-Age lets the browser cache a successful preflight result.
Access-Control-Max-Age: 600
This can reduce repeated OPTIONS traffic. The value is in seconds, though browser caps vary.
Use a modest cache time for stable APIs. Avoid very long cache times while actively changing CORS policy, because clients may keep old decisions longer than you expect.
Preflight caching is not the same as HTTP response caching for the API data. It only caches the permission check.
Security boundaries
CORS is not a substitute for backend security.
CORS controls whether browser JavaScript can read a cross-origin response. It does not replace:
- Authentication.
- Authorization.
- CSRF protection.
- Rate limiting.
- Input validation.
- Tenant checks.
- Audit or security event logging.
A blocked CORS response may still mean the request reached the server. Do not rely on CORS to stop state changes. Design sensitive endpoints with proper authorization and CSRF defenses.
Read API Authentication Best Practices and API Abuse Prevention Explained for the API side of the control model.
Common mistakes
The first mistake is allowing every origin with credentials. That turns CORS into an accidental trust policy.
The second mistake is allowing Authorization in the real request but forgetting it in Access-Control-Allow-Headers.
The third mistake is requiring authentication on OPTIONS before CORS middleware runs.
The fourth mistake is returning CORS headers only on successful responses. Error responses also need CORS headers if the browser should expose them to the frontend.
The fifth mistake is treating Postman or curl tests as proof that browser CORS will work. Non-browser clients do not enforce CORS.
The sixth mistake is using CORS to hide data instead of enforcing authorization on the server.
Debugging checklist
When a preflight fails, check:
- What is the exact
Originheader? - Does the server allow that origin exactly?
- What method is in
Access-Control-Request-Method? - Are all requested headers allowed?
- Are credentials being sent?
- Is
Access-Control-Allow-Credentialsrequired? - Is
Access-Control-Allow-Originincorrectly set to*? - Does the route handle
OPTIONS? - Do gateway, CDN, and app layers all preserve the needed headers?
- Do error responses include CORS headers too?
Browser devtools usually show the failed preflight request. Inspect the OPTIONS response before debugging the real API call.
Related reading
Read CORS Explained for Backend Developers for the broader CORS model, REST API Status Codes Explained for response behavior, and API Gateway Explained for centralized CORS handling.
For authentication and browser security, read Cookie vs Token Authentication, SameSite Cookies Explained, CSRF vs XSS, and API Authentication Best Practices. For the full sequence, browse the API Design Learning Path, Authentication Learning Path, and Backend Security Learning Path.