Repository navigation
Desktop shell hard-fails on startup after enough launches: stale dsh-auth-* cookies overflow Node's header limit (431), surfaced as "Web authentication failed" #10802
Illusory-moon
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Environment
@deepseek-ai/dsh-desktop0.2.1-rc.2 (Electron 44.7.0, bundled Node 24.21.0)cookieMaxAgeDaysleft at its default of 30 days)Symptom
Every cold start fails at startup and the window shows "DeepSeek Harness is unavailable". The crash report records:
This is deterministic: 9 consecutive launches failed the same way, each with a different shell pid. Closing and relaunching, or clearing the window state, changed nothing.
Reproduction
dsh webin a browser accumulates the same cookies for127.0.0.1and will hit the same wall after the same number of runs.Evidence
Chromium NetLog (
--log-net-log, capture mode Everything) from a failing launch shows the index request being rejected before it reaches the application:The cookie table in the desktop profile (
%APPDATA%\@deepseek-ai\dsh-desktop\Network\Cookies) held exactly 71 rows, allname LIKE 'dsh-auth-%', all forhost_key = 127.0.0.1, none for any other origin.The host itself is healthy, which rules out profile or plugin breakage. I booted the bundled
dsh-desktop-hostdirectly and probed it:GET /?token=...→303+Set-CookieGET /with that cookie →200GET /without it →401So authentication succeeds; only the oversized request is refused, and the Electron shell reports it as an auth failure because
connectDesktopWelcomechecksresponse.okand the 431 is all it sees.Root cause
The auth cookie name is
dsh-auth-+ a hash of the normalized hostname and port (see the Connection docs: cookies "bind the normalized hostname plus port in both their deterministic name and signed payload"), and it carriesPath=/,HttpOnly,SameSite=Strict, with an absolute lifetime ofcookieMaxAgeDays(default 30).HTTP cookies are port-agnostic: they are stored per host, not per origin. So:
127.0.0.1sends all previously minted cookies, because none of them are scoped to a port.maxHeaderSize). Once the accumulated cookies cross it, every index request is answered 431, and the shell can never authenticate again — a permanent brick that no restart fixes.A rough budget: ~220 bytes per cookie (47-byte name, ~170-byte signed value) → the ceiling is around 70 cookies, i.e. about 70 launches within the 30-day cookie lifetime. Anyone who launches the app more than a couple of times a day reaches this in a few weeks.
Suggested fixes
In order of preference:
dsh-auth-+ hash(normalized hostname [+ scheme]) as the name and keep the full authority (host and port) inside the signed payload, whichisAuthenticatedalready compares against the request. The browser then holds one cookie per host, replaced on every launch, and cross-port reuse still cannot authenticate because the payload's authority will not match.dsh-auth-*cookies for the same host from the session's cookie store (for a browser, this means emitting expiringSet-Cookies for the stale names).Workaround (for anyone hitting this today)
Close every desktop window, then delete only the accumulated auth rows from the cookie database (back it up first — the file is locked while the app runs):
Database path:
%APPDATA%\@deepseek-ai\dsh-desktop\Network\Cookies(SQLite). Restarting afterwards works immediately; the app mints a fresh cookie. In browser mode, clear the127.0.0.1cookies for the Web UI instead.Happy to provide the NetLog capture and the standalone probe script if they help.
All reactions