Native updater hangs indefinitely (30+ min at 0 bytes) on stalled download — no stall timeout or retry
Open 💬 0 comments Opened Jul 13, 2026 by BeheSQ
Summary
The native installer's self-update (claude update / auto-update) hung for 30+ minutes at 0 bytes downloaded on a stalled connection to the release CDN, with no stall timeout, no error, and no retry. Killing and rerunning the command immediately worked (a later retry completed the same 241 MB download in a few minutes).
Environment
- Claude Code 2.1.204 updating to 2.1.207, native install (
~/.local/bin/claude→~/.local/share/claude/versions/…) - macOS Darwin 25.6.0 (Apple Silicon)
- No proxy, macOS application firewall disabled, 200+ GB free disk
What happened
claude update(and the in-session auto-update) sat at 0 bytes downloaded for ~30 minutes with no progress, no timeout, and no failure message.- The user gave up, downloaded the binary manually, and attempted a manual install; meanwhile one of the
claude updateretries succeeded on a fresh connection —~/.claude/.last-update-result.jsonrecordedoutcome: success, 2.1.204 → 2.1.207.
Diagnosis (done after the fact)
Everything on the machine checks out, which points to a transient hung TCP connection (connected, but zero data flowing — e.g. mid-path/IPv6 blackhole):
- DNS for
storage.googleapis.comresolves fine (v4 + v6); bothcurl -4andcurl -6reach it in <0.5 s. - A ranged 20 MB download of
claude-code-releases/2.1.207/darwin-arm64/claudesucceeds (~1.3 MB/s). claude updatecompletes normally now.
So the trigger was transient network, but the updater turned a seconds-scale hiccup into a 30-minute silent hang.
Expected behavior
The updater's download should:
- Abort a stalled transfer quickly — e.g. a low-speed limit (
< 1 KB/s for 30 s→ abort), the equivalent of curl's--speed-time/--speed-limit. - Retry with a fresh connection (ideally alternating address family, since a v6 blackhole with working v4 is a common cause of exactly this signature).
- Surface progress/failure — after N failed attempts, print an actionable error instead of hanging silently.
- Optionally resume with a
Rangerequest instead of restarting a 241 MB download from zero.
Workaround
Ctrl-C and rerun claude update — a fresh connection unsticks it.