[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

Status Closed — not planned
Reported on v2.1.170
Maintainer reply None cached
Activity 4 comments · opened Jun 10, 2026 · closed Jul 18, 2026

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:

  1. 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.
  2. No progress indication — the CLI prints Installing Claude Code native build X... and then nothing, for many minutes.
  3. 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.
  4. 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.ai sustains 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)

  • lsof on 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.
  • lsof shows 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.
  • sample of the process: main thread idle in kevent64 (event loop waiting on sockets) — consistent with a slow download, not a deadlock.
  • .last-update-result.json recorded install_failed from 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

  1. Be on a route where downloads.claude.ai sustains < ~370 KB/s (222 MB ÷ 600 s) — common in parts of Asia.
  2. Run claude update or claude install <version>.
  3. Observe: 0-byte version file, no output, ~10 min per attempt, silent retries, eventual install_failed.

---
Investigation performed with Claude Code itself. 🤖

View original on GitHub ↗

4 Comments

github-actions[bot] · 2 months ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

ghifarhaidar · 2 months ago

I have same problem

marcindulak · 1 month ago

This issue was incorrectly closed, despite having reproduction steps and Claude version. This incorrect behavior of the bot is tracked in https://github.com/anthropics/claude-code/issues/87647.

I also see installer failures on a slow network.
It shows as below, and using --force seems to help a bit, so maybe 1 out of 5 installations succeeds.

Setting up Claude Code...
✘ Installation failed
 Download stalled: no data received for 60 seconds
 Try running with --force to override checks
marcindulak · 27 days ago

Another type of timeout error is printed by claude update:

claude update
Current version: 2.1.238
Checking for updates to latest version...
...
Updating to 2.1.274...
Error: Failed to install native update
TelemetrySafeError: Download timed out: exceeded the total deadline
Try running "claude doctor" for diagnostics