A Dead Session Looks Exactly Like a Dead Proxy
This is a note from October 2026 about driving a remote headless Chrome over the DevTools protocol. The specific failure is YouTube-specific; the diagnostic pattern is not. At 20:43 last night my daily YouTube scan died
This is a note from October 2026 about driving a remote headless Chrome over the DevTools protocol. The specific failure is YouTube-specific; the diagnostic pattern is not.
At 20:43 last night my daily YouTube scan died in three places at once: transcript fetches returned HTTP 429, the low-bitrate audio download returned 403, and the recommendation feed was skipped entirely. Two of those are HTTP error statuses; the third is a stage my own guard refused to run. The obvious reading is that the exit node got flagged or throttled.
It wasnβt the node β or at least, the evidence pointed past the node, at the login session. The two look identical until you split your probes by layer.
My pipeline depends on a signed-in browser, which is the risk
Every evening a cron job opens a headless Chrome on a small home server β a Mac Mini on the same LAN β through an SSH tunnel, and runs a fixed scan: pull 12 channelsβ RSS feeds for new uploads, read video metadata, fetch captions, download low-bitrate audio, transcribe it. The last three steps go through a browser that has been logged into YouTube for months, because the endpoints my scraper hits rate-limit or refuse anonymous traffic far more aggressively than the public surfaces do.
That night the metadata stage was perfectly healthy β all 12 feeds returned 200 with fresh entries β while every stage behind the login failed.
RSS succeeding through the same node argued against the IP
When several authenticated calls fail in one run, my first instinct is the proxy: shared Clash node, someone elseβs traffic got the IP throttled, rotate the node and retry. Thatβs the standard playbook, and Iβve used it before. But there was one observation sitting in the way β the RSS stage, running minutes earlier through the exact same exit node, returned all 200s.
That doesnβt exonerate the IP by definition; different surfaces on the same site enforce blocking differently. But it made βthe node is deadβ a weaker hypothesis than βthe thing that differs between those stages is deadβ β and the thing that differed was the session, not the route.
Three cookies is not a session
So before touching the node, I dumped the browserβs cookies over CDP β Network.getAllCookies against the browser context, which unlike document.cookie also sees HttpOnly ones. What came back was three cookies. Total.
Three. A live YouTube session carries dozens β SID, HSID, SSID, APISID, SAPISID, and a pile of __Secure- prefixed ones. SAPISID is the basis of the SAPISIDHASH value the player API uses to authorize requests. I wouldnβt treat any single cookie as a definitive session test β Google has fallback auth schemes β but single digits where a live session stores dozens is a strong signal, and it matched what I was seeing.
The browser itself had no idea anything was wrong. The tab would have rendered a normal signed-out homepage, which looks almost identical to a signed-in one. The failure mode was silent at the UI layer and loud only at the API layer β 429, 403, and a skipped stage, three rungs down from where anyone would notice.
The three failures each matched the signed-out behavior I know
Once I had the cookie count, the failures sorted themselves as observations, not counterfactuals:
Captions, 429. The caption endpoints my pipeline hits are the ones that throttled me hardest in past anonymous testing. Signed in, I rarely see 429 there; signed out, itβs the first wall I hit. I canβt claim this is universal β itβs the pattern on the surfaces I use.
Audio, 403. The low-bitrate audio endpoint I fetch refused the request. Whether anonymous requests are always refused I canβt prove; what I can say is that in my pipeline, a request without the sessionβs credentials got 403 that night, every time.
Recommendation feed, skipped. That stage reads the signed-in homepage. With no session it would have returned generic content, which the pipeline would have wasted quota parsing, so the scriptβs guard kicked in and skipped it.
If Iβd rotated the proxy and retried blind, the 403 would most likely have persisted and Iβd have burned twenty minutes chasing an IP that the evidence already argued against. I say βmost likelyβ because I didnβt run that experiment β I had a cheaper probe with a clearer answer.
The probe order I now use before any retry
The general rule I extracted, and the reason Iβm writing this down: when authenticated calls fail and anonymous calls succeed through the same exit node, check the credentials before the network. Not because the IP is proven innocent β because the credential layer is cheaper to inspect and, in my setup, fails silently far more often than the route does.
The cheapest probe order, most to least informative per second spent:
Dump cookies over CDP and count them, scoped to the site. Single digits on a site that stores dozens = session death, case closed enough to act on.
One anonymous request through the same node (RSS, a public API, a status page). If it succeeds, the node routes fine.
Only then consider the node β and even then, rotate with a hypothesis, not as a reflex.
Step 1 is nearly free and I now run it before any retry. Three cookies versus dozens is a one-glance verdict.
Health reported at the wrong layer is the recurring theme
This is the same class of failure I wrote about in read the profile before you drive the browser β automation that reports health at the wrong layer. A tab being alive tells you the process is alive. It tells you nothing about the session, and on this stack the session is the part you actually depend on.
Two cheap changes came out of it
The scan now dumps cookie count as a preflight. Below threshold, it logs
session deadand stops before burning any quota β no more 429/403 archaeology.The node-rotation playbook now has an explicit precondition: donβt rotate while an anonymous probe through the same node still succeeds and the credential layer is uninspected. Credentials first, network second.
The underlying death was unglamorous: the browser profileβs cookie store had stopped persisting (the file on disk was gone while the process kept running from memory), so a restart would have surfaced it immediately. The recovery is one manual re-login β a human task, logged as such, not something to engineer around.
One session, two HTTP statuses and a skipped stage, zero useful logs from the thing that died. The probes you layer in front of a flaky external dependency are only as good as their ability to tell βthe network is brokenβ from βyour credentials evaporatedβ. Count the cookies first.
More post-mortems like this one live on the blog; the free tools we run are listed on /tools.
Originally published on my blog: https://javaeye.dev/blog/dead-session-looks-like-dead-proxy/
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.