WebTech1223411 logo WebTech1223411Web tech, read closely
Browsers

How Browsers Decide Which Cookies to Send With a Request

Most developers set a cookie, watch it appear in storage, and assume it rides along on every request after that. It does not.

A browser weighing a set of stored cookies against an outgoing request

Most developers set a cookie, watch it appear in storage, and assume it rides along on every request after that. It does not. The browser runs a small set of rules on each outgoing request and decides, cookie by cookie, which ones belong in the Cookie header and which stay home. Knowing those rules turns a whole class of confusing bugs, the login that works on one subdomain but not another, the session that vanishes after a redirect from a payment page, into something you can reason about instead of guess at.

A cookie is a short name and value the server asks the browser to keep, along with a few attributes that describe its reach. The browser stores all of this in a per-profile cookie jar, grouped by the site that set each entry. The value itself is opaque to the browser. It never inspects a session token or tries to understand it. All the logic that matters for delivery lives in the attributes, Domain, Path, Secure, HttpOnly, SameSite and an expiry, so reading those attributes is the whole game when a cookie misbehaves.

Domain and path scope run the first filter

Before anything else, the browser checks whether a stored cookie even applies to the URL you are requesting. The Domain attribute sets how wide the reach is. A cookie scoped to a parent domain travels down to its subdomains, say an app host and an api host sharing that name, while one with no Domain set stays on the exact host that issued it. Path narrows it further, so a cookie with Path set to /account only attaches to requests under that path. If either check fails, the cookie is skipped silently, which is exactly why a token set on the apex domain can seem to disappear on a subdomain.

The Secure flag and the connection it demands

A cookie marked Secure is only sent over HTTPS. Request the same resource over plain HTTP, perhaps through an old hardcoded link or a local test served without TLS, and the browser leaves that cookie out entirely. This trips people up on staging environments that mix protocols. The flag protects the token from leaking across an unencrypted hop, and the browser enforces it without warning you. If a session works in production but evaporates on a local build served over HTTP, the Secure flag is the first attribute to inspect.

SameSite and the rise of cross-site rules

SameSite is the attribute that reshaped cookie delivery. Set to Strict, a cookie never attaches to a request that originated from another site, so a user arriving from an external link lands logged out even with a valid session stored. Set to Lax, the default in current browsers, it rides along on top-level navigations but not on background requests like images or embedded frames. Set to None, it travels everywhere, but browsers then require the Secure flag as well. A payment redirect that drops a session almost always points back to a SameSite value stricter than the flow needs.

Expiry, session cookies and the jar between tabs

An expiry decides how long a cookie survives. Give it an explicit Expires date or a Max-Age and it persists on disk until that moment arrives, outliving restarts. Leave both off and it becomes a session cookie, meant to die when the browsing session ends. The catch is that session restore features keep many of these alive across restarts, so a cookie you expect to clear can linger. Clock skew between the user's device and the server can also expire a cookie earlier or later than intended, which makes expiry worth checking when logins feel random.

Once the browser has gathered every cookie that passed the checks above, it packs them into a single Cookie header, pairs separated by semicolons. Order follows a loose rule, longer paths tend to come first, but you should never rely on ordering to tell two cookies with the same name apart. That duplicate-name situation, one cookie on the apex and another on a subdomain sharing a name, is a frequent source of a server reading the wrong value. Giving cookies distinct names or tightly scoped domains removes the ambiguity before it reaches your handler.

Seeing exactly which cookies went out

Guesswork ends the moment you open the Network panel in your browser tools, pick a request, and read its request headers. The Cookie header shows precisely what the browser chose to send. The Application or Storage panel lists every stored cookie with all its attributes laid out in columns, so you can confirm Domain, Path, Secure and SameSite at a glance. Comparing the two answers the real question fast: was the cookie filtered out before the request, or did it never get stored with the attributes you expected in the first place.

Frequently asked questions

Why does my cookie work on the main domain but not a subdomain? The Domain attribute was almost certainly left unset, which pins the cookie to the exact host that issued it. Set Domain to the parent domain so it reaches every subdomain under it.

Does HttpOnly change whether a cookie is sent? No. HttpOnly only hides a cookie from JavaScript running on the page. The browser still attaches it to matching requests exactly as it would any other cookie, so delivery rules are unaffected.

Why did a cookie stop arriving after a redirect from another site? That is SameSite at work. A value of Strict blocks the cookie on cross-site navigations, and Lax blocks it on background requests. Loosen it only as far as the flow genuinely requires.

Reading the jar before guessing

Cookie delivery feels unpredictable right up until you see it as a short checklist the browser runs on every request. Scope, protocol, cross-site policy and expiry each get a vote, and any one of them can quietly hold a cookie back. When a session behaves strangely, open the storage view, read the attributes, then open the network view and read the header that actually went out. The gap between those two tells you whether the fix belongs in how you set the cookie or in how you are requesting the resource.

LV
Lorenzo Vidal

Lorenzo started as a visual designer and moved into CSS after watching too many of his layouts fall apart on phones. He writes about front-end craft, interfaces and accessibility, and still tests everything with the keyboard first.

More posts by Lorenzo

More in Browsers

01doorganico 084goad 3hot8 4465456 after5internprogram ahandfulofblessings ahmadpc ahomcybersecurity allodialresources annodex antiquesandperiodcollectibles aotc asianworldkashmir beedlectrics bloggertemplatefree bluefeatheragency bodyweightsolution campaign08blog carfixadvisor catstreetcollective cbstvsports cnfanspurchasing committeeof500yearsofdignityandresistance covertopsdjs cs-kaiyuangame cuestacomunicaciontotal cxoutlet dancebetgame deskgearhub destinyvillastay detectmagazine di33 diamondsteelbuildings donmo dyanadropship emarsysfinance emimattl escapechan eskitarih evautoplay everythingweddings-orlando farmzone feedviewerapp foxstudiosscratch gamevui123 gleasongrade greetingsday hacklabasu haskell iw-kaiyun jagoanproperti jilidskripsi joltbusinessfinance juegodepokergratis juegospucca kaeru-festival latestmehndidesigns lestanzediottaviano litemagazines localcommunityhero lustrsazan mariashebets menswheels newwebstechs1 nikkit ootheday oxigenvpn plurfitness prefetial probudgetcarpetcleaning psychicmrsmartin pyaten qvantor rejoignezlogis rexzbot riselayouts ruchin rwxqsgd5 sakaltime shibiaowang shop-bot skrtips strcoding tetapatrium topselller uneplanteartificielle vipertechcr wo-kygaming yamaha-mekar yeknava yoybuysheets zenunwa yamaha-mekar jilidskripsi ankertoto ankertoto ankertoto ankertoto