[BUG] Native installer: in-memory buffering + no progress + 10-min hard timeout + restart-from-zero retries make updates impossible (and look like a deadlock) on slow routes to downloads.claude.ai
Open 💬 0 comments Opened Jun 10, 2026 by houyangzhao
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code (2.1.170)
What's Wrong?
Summary
On network routes where downloads.claude.ai throughput is below ~370 KB/s, the native installer (claude update / claude install) can mathematically never succeed, and the failure mode looks exactly like a deadlock: zero progress output, the target version file stays at 0 bytes for 10+ minutes, then a silent install_failed. The combination of design choices that causes this:
- The entire ~222 MB binary is buffered in memory and only written to disk at the end. The destination file (
~/.local/share/claude/versions/<ver>) is created upfront as a 0-byte placeholder, so watching the filesystem shows no progress at all. - No progress indication — the CLI prints
Installing Claude Code native build X...and then nothing, for many minutes. - A ~10-minute overall timeout aborts the attempt regardless of whether data is actively flowing. We observed an attempt being killed at ~220 / 222 MB (99%), all buffered data silently discarded.
- Retries restart from byte 0 (no Range/resume). With slow throughput every retry also hits the 10-minute ceiling, so 3 retries waste ~30 minutes and 3× the bandwidth, then fail.
Environment
- macOS arm64 (Darwin 25.5.0), Claude Code 2.1.169 → 2.1.170, native install
- Network: route to
downloads.claude.aisustains only ~100–250 KB/s, while the legacy GCS endpoint is ~10× faster on the same connection, same moment, same file:
$ curl -r 0-8388607 -o /dev/null -w 'speed=%{speed_download}B/s time=%{time_total}s\n' \
https://downloads.claude.ai/claude-code-releases/2.1.153/darwin-arm64/claude
speed=257173B/s (timed out at 30s with 7.7/8 MB)
$ curl -r 0-8388607 -o /dev/null -w 'speed=%{speed_download}B/s time=%{time_total}s\n' \
https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases/2.1.153/darwin-arm64/claude
speed=2160174B/s time=3.88s
Evidence (from live-debugging a stalled claude install 2.1.153)
lsofon the stalled installer: healthy ESTABLISHED TLS connections; per-connection counters on our gateway showed data steadily flowing at ~100–250 KB/s — not hung, just slow with zero feedback.lsofshows no temp file open for writing; process RSS grew in lockstep with bytes transferred (reached ~505 MB), confirming full in-memory buffering.- Gateway cumulative download counter exceeded the file size (254 MB transferred for a 222 MB file): attempt #1 was killed by the overall timeout at ~220/222 MB and the download restarted from zero.
sampleof the process: main thread idle inkevent64(event loop waiting on sockets) — consistent with a slow download, not a deadlock..last-update-result.jsonrecordedinstall_failedfrom a previous day's auto-attempt, matching the same mechanism.
This failure mode actively misleads users into killing the process and filing "updater is deadlocked" reports (we initially mis-diagnosed it that way too). Possibly related: #66213 (desktop app, runaway cumulative downloads from the same CDN — consistent with a "timeout → discard → restart from zero" loop).
Expected Behavior
- Stream the download to a temp file on disk instead of buffering ~222 MB in memory.
- Print download progress (bytes or %).
- Use a stall/idle timeout (no bytes for N seconds) rather than a hard total-duration cap — or at least make the cap generous when data is flowing.
- Resume retries with HTTP Range requests instead of discarding hundreds of MB.
- Optionally: keep the GCS endpoint as a fallback, or allow overriding the download base URL via an env var, since it remains reachable and fast on routes where the new CDN is slow.
Steps to Reproduce
- Be on a route where
downloads.claude.aisustains < ~370 KB/s (222 MB ÷ 600 s) — common in parts of Asia. - Run
claude updateorclaude install <version>. - Observe: 0-byte version file, no output, ~10 min per attempt, silent retries, eventual
install_failed.
---
Investigation performed with Claude Code itself. 🤖