Access-Control-Allow-Credentials
Cross-origin requests exclude cookies and credentials
by default. The Access-Control-Allow-Credentials
response header indicates whether the browser exposes
the response to front-end JavaScript when the
request's credentials mode is include, as part of
the CORS protocol.
Usage
Cross-origin requests default to excluding credentials such
as cookies,
Authorization headers, and TLS client
certificates. When a client sets the credentials mode to
include, the server must return
Access-Control-Allow-Credentials with a value of true
for the browser to expose the response body and headers to
the calling script.
During a preflight exchange, this header signals whether
the actual request is permitted to carry credentials. If
the preflight response omits the header or sets a value
other than true, the browser blocks the credentialed
request entirely.
For simple CORS requests (those without a preflight step, such as a basic GET), the browser still checks the header after receiving the response. If the header is missing, the response is silently discarded and never reaches the calling code.
Note
When credentials are included, the
Access-Control-Allow-Origin
header must specify an explicit origin. The wildcard
* is not permitted alongside credentialed requests.
Values
true
The only valid value. Including the header with true
tells the browser to expose the response when credentials
are present.
Access-Control-Allow-Credentials: true
Omitting the header or sending any other value has the same effect: the browser treats the response as non-credentialed and withholds the body from JavaScript.
Example
A front-end application sends a cross-origin fetch with credentials included. The server responds with the credentials header, an explicit origin, and a Vary directive so caches distinguish between origins.
Access-Control-Allow-Origin: https://app.example.re
Access-Control-Allow-Credentials: true
Vary: Origin
During a preflight for a credentialed POST request, the server confirms both the allowed method and credential support.
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.re
Access-Control-Allow-Methods: POST
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 3600
Vary: Origin
Troubleshooting
Credentialed cross-origin requests fail silently when any part of the CORS chain is misconfigured.
Cookies not sent cross-origin despite the server returning
Access-Control-Allow-Credentials: true. The client-side code must opt in to sending credentials. In the Fetch API, passcredentials: 'include'in the request options. In XMLHttpRequest, setwithCredentials = truebefore callingsend(). Without this flag, the browser strips cookies and Authorization headers from cross-origin requests regardless of the server response.Console shows "Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true." When Access-Control-Allow-Credentials is
true, the Access-Control-Allow-Origin header must contain an explicit origin. Read the incoming Origin header, validate the value against an allowlist, echo the matched origin back, and addVary: Originto the response. The same rule applies to Access-Control-Allow-Headers and Access-Control-Allow-Methods: wildcards in those headers are treated as literal strings during credentialed requests.fetch()call missingcredentials: 'include'. The Fetch API defaults tocredentials: 'same-origin', which excludes credentials on cross-origin requests. Pass{ credentials: 'include' }explicitly. Check the Network tab in DevTools and inspect the request headers. If theCookieheader is absent on the outgoing request, the client did not opt in.XMLHttpRequest missing
withCredentials = true. Similar to the Fetch API, XMLHttpRequest does not send cookies cross-origin unlesswithCredentialsis set totrue. This property must be set before callingxhr.open()orxhr.send(). Libraries like Axios expose this as{ withCredentials: true }in the request config.SameSite cookie attribute blocking cross-origin delivery. Modern browsers default to
SameSite=Laxwhen no SameSite attribute is set. Lax cookies are not sent on cross-origin POST or sub-resource requests. SetSameSite=NoneandSecureon cookies that must travel cross-origin. Verify the attribute in DevTools under ApplicationCookies. Without
Secure, browsers rejectSameSite=Nonecookies entirely.Third-party cookie phase-out blocking credentials. Chrome and other browsers are restricting third-party cookies. Cross-origin requests relying on cookies set by a different domain face increasing breakage. Where possible, move to token-based authentication using the Authorization header, or adopt the Storage Access API to request cookie access explicitly. Test in Chrome with the "Third-party cookie phaseout" flag enabled to surface problems before rollout.
See also
- Fetch Standard: HTTP Access-Control-Allow-Credentials
- Access-Control-Allow-Origin
- Access-Control-Allow-Headers
- Cookie
- Authorization
- CORS
- HTTP headers