Repository navigation
[bug]Desktop startup fails with “Web authentication failed” after ~70 launches (auth cookie header exceeds Node’s 16 KiB limit) #11344
Joey-K-tsubame
started this conversation in
Ideas
Replies: 1 comment
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: DSH Desktop 0.2.1-rc.3 (Windows x64, Electron 44.7.0, Node 24.21.0). Also present in source at 0.2.2-alpha.2 (f3803c9).
Symptoms
Launching DSH Desktop fails with “DeepSeek Harness is unavailable … The application could not start or stopped unexpectedly.” / desktop welcome: Web authentication failed (crash log under %APPDATA%@deepseek-ai\dsh-desktop\logs).
It fails on every launch. Reinstalling doesn’t help. Closing the app and deleting Network\Cookies makes it start again — until it recurs after roughly 70 more launches.
Reproduction
Launch and quit DSH Desktop repeatedly (~70 times); each launch uses a new random Host port.
Network\Cookies accumulates one dsh-auth-* cookie per launch (30-day Max-Age, HttpOnly, SameSite=Strict, 173-byte value).
At ~71 cookies the Cookie request header reaches ~16.2 KB; Node’s default http.maxHeaderSize is 16,384 bytes, so the Host returns 431.
The desktop surfaces any non-2xx as Web authentication failed.
Quick check: SELECT COUNT() FROM cookies WHERE host_key='127.0.0.1' AND name LIKE 'dsh-auth-%'.
Root cause
apps/desktop-host/src/index.ts starts the Host with --port 0, so the authority changes on every launch.
packages/client/connection/src/browser-auth.ts names the cookie dsh-auth-<sha256(authority)>, so each launch creates a new cookie instead of overwriting the previous one; Max-Age is 30 days.
apps/desktop/src/main.ts only reads session.defaultSession cookies for the welcome handshake and never removes stale ones.
packages/host/webserver/src/index.ts uses createServer(listener) with no maxHeaderSize, so the 16 KiB default applies.
Chromium sends every 127.0.0.1 cookie regardless of port, so the header grows with each launch until the Host rejects the request.
Evidence
Failing profile’s Network\Cookies: PRAGMA integrity_check = ok; 71 rows, all host_key=127.0.0.1, Path=/, HttpOnly, SameSite=Strict, 173-byte values, distinct source_port values.
Serialized header = 16,186 bytes; http.maxHeaderSize = 16,384.
Replaying that header with an Electron UA against a default node:http server returns 431; with a short UA it returns 200.
The newest cookie’s expiry equals the failing launch + 30 days, i.e., the 303 stored cookie #71 and the following redirect already exceeded the limit.
Suggested fix
Desktop: before the welcome handshake, drop stale dsh-auth- cookies for the Host origin (they are re-minted from the launch token anyway):
const origin = new URL(ready.url).origin
for (const cookie of await session.defaultSession.cookies.get({ url: origin })) {
if (cookie.name.startsWith('dsh-auth-')) await session.defaultSession.cookies.remove(origin, cookie.name)
}
Add a regression test: a session pre-populated with N stale auth cookies must still complete the handshake.
Optional defense in depth: createServer({ maxHeaderSize: 64 * 1024 }, listener) — delays the failure, doesn’t fix accumulation.
Not recommended: a fixed cookie name — it would break multiple dsh web instances on the same host.
Impact
Any Desktop user launching the app ~70 times within the 30-day cookie lifetime; several launches a day reaches it in 1–2 weeks.
Looks like a broken install; the dialog suggests reinstalling, which doesn’t help. The only workaround is deleting Network\Cookies while the app is closed, and it recurs.
dsh web accumulates the same stale cookies per port, but browser header limits are much larger, so it is less likely to fail.
All reactions