Why is my cookie not being set? (SameSite, Secure, Domain, Path)
When a cookie "isn't being set", one of two things is happening: the browser rejected the Set-Cookie header, or it stored the cookie and is choosing not to send it. The network panel tells you which, and the fix is different for each.
First: rejected, or just not sent?
In DevTools open Network, pick the response that sets the cookie and open its Cookies tab (Firefox: Cookies in the request details). A cookie listed under the response with a warning was rejected. Then check Application → Cookies (Firefox: Storage): if the cookie is there but missing from a later request's Cookie header, it was stored and not sent.
Rejected: the browser refused the Set-Cookie
| Header | Why it's dropped | Fix |
|---|---|---|
SameSite=None without Secure | Browsers require None cookies to be HTTPS-only. | Add Secure, serve over HTTPS. |
Secure on an http:// page | Insecure pages can't set or overwrite Secure cookies (localhost excepted). | Use HTTPS, or drop Secure for local http testing only. |
Domain=other.com | A host can only set cookies for itself or a parent domain. | Set it from the right host, or leave Domain out. |
Domain=co.uk / github.io | Public suffixes are shared by unrelated sites. | Use your own registrable domain. |
__Host-sid with a Domain or Path=/x | The prefix demands Secure, Path=/ and no Domain. | Match the prefix rules or rename. |
| Over 4,096 bytes | Size limit for name plus value. | Store an ID, keep data server-side. |
Expires in the past / Max-Age=0 | Not rejected exactly: it deletes the cookie. | Check your server clock and units (seconds, not ms). |
Stored but not sent
- Path: without
Path, a cookie set by/api/loginonly comes back to/api/.... Your page at/dashboardnever sees it. Always setPath=/for site-wide cookies. - Host-only vs Domain: with no Domain, a cookie from
api.example.comis not sent towww.example.com. AddDomain=example.comif both need it (and accept that every subdomain then gets it). - SameSite=Lax (the default): not sent on cross-site POSTs, iframes, images or fetch. A payment provider posting back to your site, or your front end on another domain calling your API, hits this. Use
SameSite=None; Secureonly when you really need cross-site sending. - Schemeful same-site:
http://example.comandhttps://example.comcount as different sites, so mixed-scheme setups behave as cross-site. - Third-party cookie blocking: Safari, Firefox and Chrome with the setting on hold back cookies inside another site even with SameSite=None. For embeds, consider
Partitioned(CHIPS), which gives each top-level site its own jar.
fetch and XHR never send cookies cross-origin unless you ask
// front end on https://app.example.com calling https://api.example.com
fetch('https://api.example.com/me', { credentials: 'include' })
// the API must answer with a specific origin, not *
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Without credentials: 'include' (axios: withCredentials: true) the browser ignores Set-Cookie on the response and sends no cookies. The CORS side is in CORS with credentials.
A cookie that works everywhere on one site
Set-Cookie: __Host-sid=4f9a1c2e7b; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=1209600
Locked to this host over HTTPS, unreadable by scripts, sent on normal navigation, and gone after 14 days. Test variants in the Set-Cookie explainer, which also simulates whether each cookie would be sent for a link, a form POST or a background fetch.
Related
Want the bigger picture of what cookies are and how trackers use them? Wirebook's What is a cookie on a website? lesson shows it with a pretend café. Choosing where to keep a login token: localStorage vs cookies. Decoding a JWT you found in a cookie: decoding JWTs safely.
Server answering 431 or “Request Header Or Cookie Too Large”? See HTTP 431 explained. Forms failing with a CSRF error? See CSRF token missing or incorrect.
Checking cookies from a script or a CI job? The free Anvil Set-Cookie checker API runs these same rules and returns each reason as JSON.
Questions
Why does Chrome say this Set-Cookie was blocked because it had the SameSite=None attribute but did not have the Secure attribute?
Browsers only accept SameSite=None on Secure cookies. Add Secure and serve the response over HTTPS.
Why is my cookie only available on some pages?
It was probably set without Path, so it defaults to the folder of the URL that set it, such as /api. Add Path=/.
Why doesn't my API's cookie show up after fetch?
Cross-origin fetch ignores cookies unless you pass credentials: 'include' and the server replies with Access-Control-Allow-Credentials: true and a specific Access-Control-Allow-Origin.
Can localhost set a Secure cookie?
Yes. Browsers treat http://localhost as a secure context, so Secure cookies work there during development.
Why does my cookie vanish when I close the browser?
It has no Expires or Max-Age, so it is a session cookie. Add Max-Age (in seconds) to keep it.
Published .