Network

CORS Headers Reference

Comprehensive reference for all Access-Control-* headers , preflight flow, common CORS configurations, and error patterns with solutions.

Headers(9)

HeaderDirValuesDescription

Access-Control-Allow-Origin

Access-Control-Allow-Origin: https://app.example.com

Response* | <origin> | nullIndicates which origins are allowed to access the resource. Use "*" for public resources or a specific origin for credentialed requests.

Access-Control-Allow-Methods

Access-Control-Allow-Methods: GET, POST, PUT, DELETE

ResponseGET, POST, PUT, DELETE, PATCH, OPTIONS, HEADSpecifies the HTTP methods allowed when accessing the resource. Sent in response to a preflight request.

Access-Control-Allow-Headers

Access-Control-Allow-Headers: Authorization, Content-Type, X-Custom-Header

Response<header-name>[, <header-name>]* | *Indicates which HTTP headers can be used during the actual request. Sent in response to a preflight.

Access-Control-Allow-Credentials

Access-Control-Allow-Credentials: true

ResponsetrueIndicates whether the response to the request can be exposed when credentials (cookies, auth headers) are included. Cannot be used with wildcard origin.

Access-Control-Max-Age

Access-Control-Max-Age: 86400

Response<delta-seconds>Indicates how long (in seconds) the preflight response can be cached. Reduces number of preflight requests.

Access-Control-Expose-Headers

Access-Control-Expose-Headers: X-Custom-Header, Content-Length

Response<header-name>[, <header-name>]* | *Allows the server to whitelist headers that browsers are allowed to access in the response.

Access-Control-Request-Method

Access-Control-Request-Method: DELETE

Request<method>Used in preflight requests to indicate which HTTP method will be used for the actual request.

Access-Control-Request-Headers

Access-Control-Request-Headers: Authorization, Content-Type

Request<header-name>[, <header-name>]*Used in preflight requests to indicate which HTTP headers will be used for the actual request.

Origin

Origin: https://app.example.com

Request<origin> | nullSent automatically by browsers. Indicates the origin (scheme + hostname + port) of the request initiator.

Preflight Flow

1.Browser sends OPTIONS request with Access-Control-Request-Method and Access-Control-Request-Headers.
2.Server responds with Access-Control-Allow-* headers (and optionally Access-Control-Max-Age to cache the result).
3.If approved, browser sends the actual request. If Access-Control-Max-Age was set, no preflight for subsequent requests within that window.
Simple requests (GET/HEAD/POST with safe headers like Content-Type: application/x-www-form-urlencoded) do NOT trigger a preflight.

Common Configurations

Simple Request (public API)

Allow any origin for public read-only APIs. No credentials.

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD, POST
Access-Control-Allow-Headers: Content-Type

Note: Simple requests (GET/POST with safe headers) do not trigger a preflight. Wildcard (*) cannot be used with credentials.

Authenticated Request (specific origin)

Allow a specific trusted origin with credentials (cookies/auth headers).

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 86400

Note: With credentials, you must specify an exact origin (not *). Max-Age caches the preflight for 24 hours.

Preflight (OPTIONS) Response

Respond to a preflight request with allowed methods and headers.

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

Note: Always include Vary: Origin when returning dynamic origins. Return 204 No Content for OPTIONS preflight.

Expose Custom Response Headers

Allow the browser to read custom response headers from JavaScript.

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Expose-Headers: X-Total-Count, X-Page, X-RateLimit-Remaining

Note: By default, only CORS-safelisted headers (Cache-Control, Content-Type, etc.) are accessible. Use Expose-Headers for custom ones.

Multiple Origins (dynamic)

Allow multiple specific origins by validating and reflecting the Origin header.

Access-Control-Allow-Origin: <reflect validated origin>
Vary: Origin
Access-Control-Allow-Credentials: true

Note: Check the Origin header against an allowlist and reflect it back. Always add Vary: Origin to prevent caching issues with CDNs.

Common CORS Errors

No "Access-Control-Allow-Origin" header

Cause: Server does not return CORS headers, or the origin is not allowed.

Fix: Add Access-Control-Allow-Origin to the server response. Ensure the requesting origin is in your allowlist.

CORS policy: Cannot use wildcard in Access-Control-Allow-Origin with credentials

Cause: Using Access-Control-Allow-Origin: * along with Access-Control-Allow-Credentials: true.

Fix: Replace * with the exact origin. Never combine wildcard with credentials: true.

Response to preflight does not pass access control check

Cause: The OPTIONS preflight response is missing required ACAO/ACAM/ACAH headers.

Fix: Ensure OPTIONS requests return Access-Control-Allow-Methods and Access-Control-Allow-Headers matching the request.

"Content-Type" header not allowed

Cause: Non-simple Content-Type (e.g. application/json) triggers preflight, but ACAH does not include Content-Type.

Fix: Add Content-Type to Access-Control-Allow-Headers in the preflight response.

Request header "Authorization" not allowed

Cause: Authorization is a non-simple header not listed in Access-Control-Allow-Headers.

Fix: Add Authorization to Access-Control-Allow-Headers.

Redirect is not allowed for cross-origin requests

Cause: The server redirects the request (3xx) but browsers block CORS redirects.

Fix: Remove redirects for cross-origin endpoints. If necessary, add CORS headers on the redirect target.

Share

marduc812

2026