Set-Cookie

The HTTP Set-Cookie response header sends a cookie from the server to the client. The client stores the cookie and returns the cookie in subsequent requests using the Cookie header, enabling state management across an otherwise stateless protocol.

Usage

The Set-Cookie header instructs the client to store a name-value pair along with optional attributes controlling the cookie's scope, lifetime, and security properties. Each Set-Cookie header sets exactly one cookie. Servers sending multiple cookies include multiple Set-Cookie headers in the same response.

The general syntax is a cookie name and value separated by an equals sign, followed by optional attributes delimited by semicolons.

Set-Cookie: <name>=<value>; <attributes>

The cookie name accepts US-ASCII characters except control characters, spaces, tabs, and the separator characters ( ) < > @ , ; : \ " / [ ] ? = { }. The cookie value accepts US-ASCII characters excluding control characters, whitespace, double quotes, commas, semicolons, and backslashes. Values are optionally wrapped in double quotes.

Browsers block frontend JavaScript from reading the Set-Cookie header through the Fetch API and XMLHttpRequest. The header is a forbidden response header name in the Fetch specification. Cookies in CORS responses are ignored unless the request includes credentials.

Cookie name prefixes impose additional constraints enforced by the browser, providing guarantees about where and how a cookie was set.

The __Secure- prefix requires the Secure attribute and an HTTPS Origins. This prevents HTTP-only sites from setting cookies sharing a name with a secure cookie.

Set-Cookie: __Secure-ID=abc; Secure; Path=/

The __Host- prefix adds stricter requirements: the Secure attribute, no Domain attribute, and Path set to /. This binds the cookie to the exact origin hostname, preventing subdomain interference.

Set-Cookie: __Host-ID=abc; Secure; Path=/

The __Http- prefix requires both the Secure and HttpOnly attributes and is settable only through the Set-Cookie header, not through JavaScript.

Set-Cookie: __Http-ID=abc; Secure; HttpOnly

The __Host-Http- prefix combines the restrictions of both __Host- and __Http-, creating the most restrictive cookie binding available.

Set-Cookie: __Host-Http-ID=abc; Secure; HttpOnly; Path=/

Note

The __Http- and __Host-Http- prefixes are not part of a specification update, which defines only __Secure- and __Host-. These prefixes come from a separate browser proposal and shipped in Chromium-based browsers and Firefox. Safari does not support these prefixes.

Directives

Expires

The Expires attribute sets an absolute expiration date in HTTP-date format. After this date, the client no longer sends the cookie. When omitted along with Max-Age, the cookie becomes a Session cookie removed when the client closes. Browsers adjust for clock skew using the Date header from the response.

Expires=Thu, 31 Dec 2026 23:59:59 GMT

Note

Browsers cap the Expires value at 400 days from the time the cookie is set. This limit allows sites visited roughly once a year to maintain cookies while preventing indefinite persistence.

Max-Age

The Max-Age attribute sets the cookie lifetime in seconds from the time the client receives the response. A zero or negative value expires the cookie immediately. When both Expires and Max-Age are present, Max-Age takes precedence.

Max-Age=2592000

The Cookie Store API in JavaScript also exposes a maxAge option through the cookieStore.set() method, mirroring this attribute for programmatic cookie management. The API does not allow setting both expires and maxAge on the same cookie.

Note

Browsers cap the Max-Age value at 400 days (34,560,000 seconds), matching the Expires cap.

Domain

The Domain attribute specifies which hosts receive the cookie. When set, the cookie is available to the specified domain and all its subdomains. When omitted, the cookie defaults to the exact originating host, excluding subdomains (a host-only cookie). Only the current domain or a parent domain of the current host is valid. Leading dots are ignored.

Domain=example.re

Path

The Path attribute limits cookie transmission to requests matching the specified URL path prefix. The forward slash / delimits path segments. A cookie with Path=/docs matches /docs, /docs/, /docs/Web/HTTP but not / or /docsets.

Path=/

Note

The Path attribute is not a security mechanism. Any script on the same origin has access to all cookies regardless of path restrictions.

Secure

The Secure attribute restricts the cookie to HTTPS connections. The browser never sends a secure cookie over unencrypted HTTP. Insecure origins cannot set cookies with this attribute. Localhost is exempt from the HTTPS requirement during development.

HttpOnly

The HttpOnly attribute blocks JavaScript access to the cookie through document.cookie, the Cookie Store API, and other DOM interfaces. The cookie is still sent with HTTP requests initiated by JavaScript through fetch() and XMLHttpRequest. This attribute mitigates cross-site scripting (XSS) attacks attempting to steal cookie values.

SameSite

The SameSite attribute controls whether the browser sends the cookie with cross-site requests. Three values are defined.

Strict sends the cookie only with same-site requests. Cross-site navigations, including clicking a link from an external site, do not include the cookie.

Lax sends the cookie with same-site requests and cross-site top-level navigations where the URL bar changes. Subresource requests, fetch() calls, and iframe navigations do not include the cookie. Most browsers default to Lax when no SameSite attribute is specified.

None sends the cookie with all requests, including cross-site requests. The Secure attribute is required when using SameSite=None. Cookies from a different scheme (HTTP vs HTTPS) are treated as cross-site.

SameSite=Lax

Partitioned

The Partitioned attribute stores the cookie in partitioned storage keyed to both the cookie origin and the top-level site. A partitioned cookie set by cdn.example.re embedded on shop.example.org is only sent when cdn.example.re is embedded on shop.example.org, not when embedded on other sites.

This attribute is part of the Cookies Having Independent Partitioned State (CHIPS) proposal. The attribute enables legitimate cross-site cookie use cases like embedded widgets, CDN load balancing, and headless CMS providers without granting full cross-site tracking capability.

The Secure attribute is required. The __Host- prefix is recommended to bind the cookie to the exact origin.

Set-Cookie: __Host-sess=abc; SameSite=None; Secure; Path=/; Partitioned

Supported by Chromium-based browsers and Firefox. Safari partitions third-party cookies by default through a separate mechanism and does not use this attribute.

Example

A session cookie with no expiration attributes. The cookie is removed when the client session ends.

Set-Cookie: sessionId=38afes7a8

A persistent cookie with a 30-day lifetime. The Max-Age attribute sets the expiration relative to the current time.

Set-Cookie: id=a3fWa; Max-Age=2592000

A cookie with security attributes suitable for Authentication tokens. The HttpOnly attribute blocks JavaScript access, Secure restricts to HTTPS, and SameSite=Strict prevents cross-site transmission.

Set-Cookie: __Host-token=eyJhbGci; Secure; HttpOnly; SameSite=Strict; Path=/

A partitioned third-party cookie for a cross-site embed. The Partitioned attribute isolates the cookie to the specific top-level site where the embed appears.

Set-Cookie: __Host-embed=34d8g; SameSite=None; Secure; Path=/; Partitioned

Multiple cookies set in a single response. Each cookie requires its own Set-Cookie header.

Set-Cookie: theme=dark; Path=/; Max-Age=31536000
Set-Cookie: __Host-sid=x8Kp2; Secure; HttpOnly; SameSite=Lax; Path=/

Takeaway

The Set-Cookie header sends cookies from server to client with attributes controlling lifetime, scope, and security. The Secure, HttpOnly, SameSite, and Partitioned attributes collectively address common cookie security and privacy concerns, from XSS mitigation to cross-site tracking prevention.

See also

Last updated: March 6, 2026