Guide

Debugging Cookies in Browser Developer Tools

A practical routine for finding out why a cookie was not set, not sent or not deleted, using the network and application panels of browser developer tools.

Key takeaways

  • Follow the cookie through its two moments: when the server sets it and when the browser sends it.
  • The network panel shows Set-Cookie on responses and, in many browsers, why a cookie was blocked or filtered.
  • The application panel lists name, value, domain, path, expiry, size and flags for every stored cookie.
  • When a cookie is not sent, check host, path, scheme, expiry, SameSite and third-party context in that order.
  • Cross-origin fetch needs credentials enabled and CORS headers that allow credentials and name a specific origin.

Start from the wire, not from guesses

Cookie bugs are frustrating because the failure is silent. A browser that rejects a cookie rarely throws an error in your code. The page simply behaves as if the user were logged out. The most reliable way to debug is to follow the cookie through its two moments: when the server sets it, and when the browser sends it. Browser developer tools expose both, and the exact panel names vary a little between browsers, but the ideas are the same.

Step one: confirm the server sent Set-Cookie

Open the network panel, reload the page with the log preserved, and click the response that should have created the cookie. In the response headers, look for Set-Cookie. If it is missing, the bug is on the server or in a proxy. Check that the code path actually ran, that a cache or content delivery network is not stripping or serving a stored copy of the response, and that you are not looking at a redirect step where the cookie was set on a different response. Note that a response served from a shared cache should not normally carry a personal Set-Cookie header, so check your caching rules.

Many browsers show a small warning marker next to a Set-Cookie header when the browser did not accept it, with a short reason in a tooltip. Typical reasons include a Secure cookie received over plain HTTP, a SameSite=None cookie without Secure, a Domain that does not match the host, a violated prefix rule, or a cookie that exceeds the size limit.

Step two: inspect the cookie jar

Open the application panel, called storage in some browsers, and select cookies for the site. You should see the name, value, domain, path, expiry, size and flags such as HttpOnly, Secure, SameSite and Partitioned. Compare these with what you intended. A frequent surprise is a domain column showing the host only, when you expected a parent domain, or a path that is narrower than expected because you did not set Path explicitly. Expiry shown as session means no Expires or Max-Age was applied.

Step three: confirm the browser sent the cookie

Select a later request in the network panel and open the cookies tab of the request. Most tools list the cookies that were sent and, helpfully, the ones that were filtered out with a reason. If the Cookie request header is absent, one of the matching rules failed. Work through the checklist below.

  • Host: does the request host match the cookie domain? A host-only cookie does not go to subdomains.
  • Path: does the request path fall under the cookie path?
  • Scheme: is the cookie Secure while the request uses plain HTTP?
  • Expiry: has the lifetime already ended, perhaps due to a wrong client clock?
  • SameSite: did the request start from another site, such as a link, a frame or a form post?
  • Third-party context: is the request made from an embed in a browser that blocks or partitions third-party cookies?

Symptoms and likely causes

SymptomLikely causeWhere to look
Set-Cookie missing in the responseServer code path, proxy or cacheNetwork panel, response headers
Cookie rejected on arrivalSecure over HTTP, bad Domain, prefix rule, SameSite=None without Secure, sizeWarning marker beside Set-Cookie
Cookie stored but not sentHost, path, scheme, expiry or SameSite mismatchRequest cookies tab
Missing on cross-origin fetchCredentials not enabled or CORS headers missingFetch options and response headers
Logout does not log outDeletion header used a different name, domain or pathApplication panel, cookie list

What are the common cookie bug patterns?

Cookie set but never sent back. Usually a scope mismatch, such as a path set from a deeper address, or Secure used on a development server without HTTPS. Another cause is a fetch call from script to a different origin without credentials enabled. For cross-origin fetch, the call must opt in to credentials (by default, MDN notes, they are included only on same-origin requests), and the server must respond with matching CORS headers that allow credentials and name a specific origin rather than a wildcard.

Login works, then disappears on the next page. Often the cookie is set with a Path that does not cover the later pages, or a redirect moves between two hosts, for example from the bare domain to www, and the cookie belongs only to one of them.

Works in one browser, fails in another. Differences in third-party cookie handling, SameSite enforcement details, or support for newer attributes. Test the same flow in at least two engines, and check any privacy mode.

Logout does not log out. The deletion header used a different name, domain or path from the original, so a different cookie was cleared. Match all three exactly and set Max-Age to zero.

Cookie is too large. Browsers drop oversized cookies silently. Look at the size column and move bulky data to the server.

What goes wrong with cross-site cookies and embeds?

When your page is inside an iframe on another site, treat it as a separate world. Check the cookie in the context of the embedded frame, not just the top page. Look at whether your cookie carries SameSite=None and Secure, whether the browser blocks third-party cookies by default, and whether a partitioned cookie is stored under a different key than the one you inspect. Some tools offer a toggle to simulate blocking third-party cookies, which lets you reproduce the problem on demand.

Which habits make cookie debugging easier?

  • Test in a private window to start from an empty cookie jar.
  • Clear only the site cookies you are debugging, not the whole browser profile.
  • Use command-line tools to inspect raw headers, for example by requesting a URL and printing response headers, to rule out browser effects.
  • Log the incoming Cookie header on the server during debugging, but never log full session values in production.
  • Write a small automated test that checks the Set-Cookie header contains the flags you expect.

What if nothing explains the problem?

If every check passes and the cookie still misbehaves, reduce the problem. Create the smallest page and server route that set and read one cookie, confirm that works, then add your real attributes one at a time. The moment the cookie stops working points directly at the guilty attribute or the intermediary, such as a proxy, cache or security filter, that rewrites headers.

Sources and further reading

Frequently asked questions

Why does the browser silently ignore my Set-Cookie header?

Browsers reject cookies that break their rules, such as Secure over HTTP, a mismatched Domain, a broken prefix rule or SameSite=None without Secure. The developer tools network panel usually shows a warning with the reason.

Why is my cookie missing on a fetch request to another origin?

Cross-origin fetch does not include cookies unless you enable credentials, and the server must answer with CORS headers that allow credentials and name the exact origin.

How can I see why a cookie was filtered out of a request?

Open the request in the network panel and check its cookies tab. Many browsers list the blocked cookies and give a short reason, such as a SameSite or Secure restriction.

Is it safe to log the Cookie header on my server?

Only briefly, in a development setting. In production, session values are credentials, so avoid logging them in full.

All guides