Repository navigation
dsh-desktop fails to start after ~70 launches: dsh-auth cookies accumulate per random port and overflow Node's 16 KiB request-header limit (431) #12911
Replies: 3 comments 1 reply
|
Thanks — and sorry, I should have searched before posting: this is already reported several times, e.g. #11215 (answered, same measurements) and #11397 (source-level check confirming it is still unfixed at Two things this machine adds that I did not find in those threads: 1. A config-level mitigation that needs no code change. - id: connection
config:
cookieMaxAgeDays: 1
2. A second trap that deserves its own report. The startup-failure dialog's third button — "Disable third-party plugins, back up profile patch, and restart" — runs The patch file is backed up. The bundle list is not: for a profile with ~35 plugins that is the destructive half of the operation, and it is not mentioned in the button label. Because a 431 makes this dialog appear on every launch, any user hitting this cookie bug is one click away from losing their bundle list. Suggestions: keep a copy of the previous |
|
Thanks for the write-up — the root-cause chain matches exactly what I hit this morning on Windows, and I have a few measured numbers that your derivation doesn't cover, plus a cleanup script that others can reuse. I'm posting this as a supplement, not a new report: I see this has been filed several times already (#12649, #12739, #12911), so everything below is meant to be additive. Measured sizes (one machine, 71 historical cookies)Where your analysis is code-derived, these are from the actual Chromium cookie DB (
So the budget math becomes concrete: That puts the threshold at the 70th cookie, which lines up with the "~70 launches" figures others reported — but now it's a number you can compute for any machine rather than estimate. Caveat: 225.5 B is a mean over my 71 samples. It depends on the length of the payload/signature (the 171–173 spread above), so other installs will differ by a few bytes per cookie; the 574 B header estimate is also browser-version dependent. Treat the formula as the invariant, the constants as machine-specific. What deletion looked likeBefore / after, same DB,
Note the DB is exclusively locked while the desktop is running — copying it fails with Script, if useful to othersI wrote a small wrapper that does the same thing with guardrails: powershell -File clean-auth-cookies.ps1 -WhatIf # dry run: reports counts and header size, deletes nothing
powershell -File clean-auth-cookies.ps1 # backup, then delete, then VACUUMBehaviour:
I can attach the file or open a PR with it under Not asking for a timelineI'm not after an ETA. Since three separate reports converged on the same mechanism, I assume it's already on your radar; the only reason I'm commenting is that the measured constants above might save the next person some arithmetic. If it's already fixed in a build I haven't tried, feel free to ignore this. |
|
This report's root-cause chain matches
One residual gap is ordering, not accumulation: on For the current build: quit fully (not just close the window), delete If it reproduces after the next desktop release, two measurements close the loop: row count of |
Uh oh!
There was an error while loading. Please reload this page.
Environment
desktop, single machine, loopback onlyapp.asar, no local patches to the shellSymptom
After a few weeks of ordinary use the desktop app stopped starting. Every launch ends with:
The host itself comes up and prints its line (
dsh web: http://127.0.0.1:<random-port>/?token=…), then the desktop shell's welcome fetch never authenticates.%APPDATA%\@deepseek-ai\dsh-desktop\logs\crash-*-host.loghas one entry per attempt (9 attempts in one morning, all identical). Restarting does not help; reinstalling does not help.Root cause
BrowserAuth.authorizeIndex()mints the session cookie only onGET /carrying a valid?token=, viasessionCookie(cookieName(authority), …), whereauthorityis the request'shost:port(requestAudience).dsh-desktopalways launches the host with a fixed argument list:--no-open --host 127.0.0.1 --port 0, so the port is different on every start.cookieMaxAgeDaysdefaults to 30, so stale cookies survive a month.Net effect: one
dsh-auth-*cookie accumulates per launch, forever.Evidence
Cookie DB at
%APPDATA%\@deepseek-ai\dsh-desktop\Network\Cookies(copied with the app closed):host_key = 127.0.0.1,path = /dsh-auth-<43-char base64url>(52 bytes each)valueis plaintext, 171–173 bytes, e.g.v1.eyJ2ZXJzaW9uIjoxLCJhdXRob3JpdHkiOiIxMjcuMC4wLjE6MTkzODci…→{"version":1,"authority":"127.0.0.1:19387",…}Request-header cost:
71 × (52 + 171 + 3) = 16,076 bytesofCookiealone.Node's HTTP server defaults to
maxHeaderSize = 16384for the request line plus all headers, and Chromium adds roughly 400 B ofHost/User-Agent/sec-ch-ua*/sec-fetch-*/Accept*. So the crossover lands at ~70 cookies: the next launch pushes the request over the limit, the server answers 431,net.fetchresolves withok === false, andconnectDesktopWelcomethrows "Web authentication failed" — with no hint that the real cause is a header-size limit.The obvious workaround has its own trap
connection.cookieMaxAgeDayscan bound the accumulation (we currently run1), but:issuedAt + maxAgeMilliseconds), not a sliding refresh;GET /?token=exchange, and after the303 → ./the token is no longer in the URL;ConnectionRecoveryConfigSchemaonly carries backoff timings (backoffBaseMs,backoffFactor,backoffMaxMs,generationReady*) — there is no re-authentication path.So a long-running instance turns every
/apicall into 401 once the cookie expires, and only a restart recovers. 30 days is what causes the startup failure; 1 day kills long-lived sessions. Neither default is right for a desktop app.Suggested fixes
authorizeIndexmints a cookie, remove every otherdsh-auth-*cookie for the same host through Electron'ssession.cookies.remove(). The jar stays at one entry per host and the authority binding is untouched.authorityin its signed payload andisAuthenticatedvalidates it. Deriving the name from the hostname alone (without the port) makes successive launches replace each other, so accumulation becomes structurally impossible.--port 0is hardcoded; a stable/reusable port would also remove the accumulation and make the GUI URL bookmarkable.Local recovery for anyone hitting this
Quit the desktop app, delete
%APPDATA%\@deepseek-ai\dsh-desktop\Network\Cookies, relaunch. On Linux/macOS the same jar lives in the@deepseek-ai/dsh-desktopuser-data directory and the same random-port behaviour applies.Happy to supply the raw cookie rows, the
crash-*-host.logfiles, or the asar excerpts forauthorizeIndex/sessionCookie/cookieNameif that helps.All reactions