GuidesHEADERS

Access-Control-Allow-Credentials

The Access-Control-Allow-Credentials response header tells the browser whether a cross-origin response may be exposed when the request carries credentials. Browsers do not send credentials cross-origin by default, and they withhold the response from code unless the server explicitly allows it. Both sides have to opt in: the server with this header, the client with a request flag.

What the header does

Access-Control-Allow-Credentials is an HTTP response header that tells browsers whether the response to a credentialed request may be exposed to the calling page.

Under CORS, credentials are cookies, TLS client certificates, and authentication headers carrying a username and password. Cross-origin requests omit them by default, and when a request does carry them, the browser blocks the response from web content unless the server acknowledged the exchange with this header.

The only valid value is true

The specification permits exactly one value. If the server allows credentialed access, it returns this header with the literal value true.

Credentialed responses need an explicit origin, never a wildcard
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Vary: Origin

# Omit the credentials header entirely when the endpoint needs no credentials.
# "false" is not a valid value.

  • The value must be the literal, case-sensitive string true.
  • If credentials are not needed, omit the header entirely instead of setting it to false.
  • If the header is missing on a response to a credentialed request, the browser blocks access to the response and logs a CORS error.

Opt in on the client

Sending credentials cross-origin requires an explicit client opt-in. A server header alone does nothing, because the browser withholds credentials until the code asks for them to be sent.

The client must opt in as well
// fetch: send cookies and HTTP auth across origins
const response = await fetch('https://api.example.com/me', {
  credentials: 'include',
});

// XMLHttpRequest: same opt-in, different flag
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/me');
xhr.withCredentials = true;
xhr.send();

With fetch, pass credentials: "include". With XMLHttpRequest, set withCredentials = true before sending. With EventSource, pass withCredentials: true in the constructor options.

Required on preflight and actual responses

When a cross-origin request triggers a preflight, the browser evaluates credential permission at both stages of the exchange.

  • The preflight request itself never includes credentials.
  • If the preflight response sets Access-Control-Allow-Credentials: true, the browser sends the actual request with credentials.
  • If the preflight response omits the header, the browser reports a network error and the actual request never fires.
  • For requests without a preflight, the browser sends credentials with the request, then blocks the response from web content when the header is missing.

Wildcards fail with credentials

Credentialed requests forbid wildcards across every CORS response header. The server must name concrete values.

  • Access-Control-Allow-Origin cannot be * and must echo the explicit origin, as covered in the Access-Control-Allow-Origin guide.
  • Access-Control-Allow-Headers cannot be * and must name each request header, as detailed in the Access-Control-Allow-Headers guide.
  • Access-Control-Allow-Methods cannot be * and must list explicit HTTP methods.
  • Access-Control-Expose-Headers cannot be * and must name the response headers scripts may read.

Common mistakes

Credentialed CORS failures usually come from a missing flag, a wildcard left in place, or a cookie policy, not from the header value itself.

  • The server sets Access-Control-Allow-Credentials: true, but the client flag is missing, so the request goes out without cookies or authentication headers.
  • The client opts in, but the server omits the header, so the browser blocks the response.
  • The server returns Access-Control-Allow-Origin: * on a credentialed request, so the browser blocks the response and ignores any Set-Cookie header on it.
  • The browser is configured to block third-party cookies, so no CORS configuration makes them appear.

Good questions.

Can Access-Control-Allow-Credentials be set to false?

No. The only valid value is the case-sensitive string true. When credentials are not needed, omit the header entirely.

Why are cookies missing even though the header is set to true?

The client must also opt in with credentials: "include" in fetch or withCredentials = true in XMLHttpRequest. Browsers configured to block third-party cookies will not send or store them regardless of CORS headers.

What happens if Access-Control-Allow-Origin is a wildcard on a credentialed request?

The browser blocks the response, logs a CORS error, and ignores any Set-Cookie headers on that response.

Does the preflight request carry credentials?

No. The preflight OPTIONS request never includes credentials. The browser sends credentials on the actual request only after the preflight response confirms Access-Control-Allow-Credentials: true.