[BUG] v2.1.113+ on linux-x64 behind HTTP CONNECT proxy: Bun runtime fetch race condition + 3 cascading regressions
[BUG] v2.1.113+ on linux-x64 behind HTTP CONNECT proxy: Bun runtime fetch race condition + 3 cascading regressions
TL;DR — root cause
Bun runtime's fetch() in the linux-x64 build hangs intermittently when used through an HTTP CONNECT proxy. This is a race condition: under strace (which slows syscalls via ptrace) it disappears completely. The arm64 build is unaffected. Same proxy works in 0.3s with curl and python urllib. There is no per-binary distribution issue — the official installer and the npm @anthropic-ai/claude-code-linux-x64 optional dep ship the identical ELF (sha256 below).
This single root cause produces several different user-visible failures, documented as Bug #1–#4 below. Bug #4 is the root; Bugs #1–#3 cascade from it (or compound it).
| | x86_64 Linux | arm64 Linux |
|---|---|---|
| 2.1.112 (bundled JS) | 10/10 ✅ | n/a |
| 2.1.114 (Bun native) | 2/10 ✅ (8 TIMEOUT) | 10/10 ✅ |
Same proxy, same ~/.claude/settings.json, same Ubuntu 24.04.3 + glibc 2.39. Only the architecture (and binary) changes.
Workaround: npm i -g @anthropic-ai/claude-code@2.1.112.
---
Environment
| | |
|---|---|
| Claude Code | 2.1.114 (also reproduced on 2.1.113) |
| Distribution | Bun single-file ELF (log paths show /$bunfs/root/src/entrypoints/cli.js) |
| OS | Ubuntu 24.04.3 LTS, kernel 6.8.0-107-generic, glibc 2.39, x86_64 |
| Network | Standard enterprise setup — all egress must traverse a local HTTP CONNECT forward proxy. No direct internet route. |
| Reference machine A | local x86_64 + Claude Code 2.1.112 (bundled JS) — works |
| Reference machine B | aarch64 + Claude Code 2.1.114 (Bun native) — works |
~/.claude/settings.json env block sets HTTPS_PROXY, HTTP_PROXY, ALL_PROXY, NO_PROXY (each in upper- and lowercase), plus OTEL_SDK_DISABLED=true, OTEL_*_EXPORTER=none, DISABLE_AUTOUPDATER=1, CLAUDE_CODE_PROMPT_CACHE_TTL=1h. Verified loaded by debug log: settingsEnv keys: HTTPS_PROXY,HTTP_PROXY,ALL_PROXY,...,OTEL_SDK_DISABLED,....
---
Bug #4 (root cause) — linux-x64 Bun runtime fetch hangs through HTTP CONNECT proxy
Symptom
POST /v1/messages is sent successfully through the CONNECT tunnel. Then 30 seconds pass with zero stream chunks coming back, the client logs Slow first byte: no stream chunk 30.0s after request sent (attempt 1), and the request hangs until the wrapper kills it at 45s. Headless mode reproduces ~75% of the time. TUI hits the same code path during startup and intermittently during long sessions.
Hard evidence
1. Same binary across distribution channels — packaging is innocent:
npm optional dep @anthropic-ai/claude-code-linux-x64 :
sha256 12bd4b0916deb06be17ffc7b2f0485e140bf00b2db3dcb78469d66723d73c27f
BuildID 052ef6d8cef1bef39149a31808f3d579db450889
size 236411520
Official installer (https://claude.ai/install.sh -- 2.1.114) :
sha256 12bd4b0916deb06be17ffc7b2f0485e140bf00b2db3dcb78469d66723d73c27f
BuildID 052ef6d8cef1bef39149a31808f3d579db450889
size 236411520
2. Network/proxy/upstream are healthy:
| Tool | api.anthropic.com | statsigapi.net | docs.claude.com |
|---|---|---|---|
| curl 8.5.0 (same env, same proxy) | 0.258 / 0.270 / 0.273 s (404) | 0.340 / 0.343 / 0.339 s (403) | 0.501 / 0.598 / 0.420 s (200) |
| Python urllib 3.13 (same env, same proxy) | 0.418 / 0.415 / 0.421 s | 0.333 / 0.337 / 0.338 s | 0.282 / 0.273 / 0.369 s |
| Bun runtime via Claude Code | 30s+ stalls, intermittent |||
tcpdump during a TIMEOUT trial captures a clean CONNECT api.anthropic.com:443 HTTP/1.1\r\nProxy-Connection: Keep-Alive\r\n\r\n request (so this is not issue #14165 "Bun ignores HTTP_PROXY" — it does use the proxy). A successful trial under strace shows TLS ClientHello → ServerHello → application data flowing both directions in the CONNECT tunnel.
3. Race condition (the smoking gun):
Without strace : 2 / 10 OK
Under strace : 5 / 5 OK (ptrace serializes syscalls and adds ~100µs/call)
ptrace overhead reliably masks the bug. Bun uses io_uring on Linux (anon_inode:[io_uring] fds visible in the strace) — the suspected location is the io_uring submission/completion path or the TLS state machine on the CONNECT-tunneled socket.
4. Architecture-selective, not network-selective:
Same proxy, same settings.json, same Ubuntu 24.04.3 + glibc 2.39. The only difference between the working machine and the broken machine is linux-arm64 vs linux-x64 Bun build.
5. Also reproduces on a different multi-core x86_64 box — not a single-vCPU artifact, not specific to the low-power Intel N150 reference machine.
6. No user-side workaround works (each tested 5×, early-aborted on 2 TIMEOUTs):
| Env var | Effect |
|---|---|
| BUN_FEATURE_FLAG_DISABLE_IO_POOL=1 | 2 TIMEOUT (no help) |
| BUN_FEATURE_FLAG_DISABLE_RWF_NONBLOCK=1 | 2 TIMEOUT (no help) |
| BUN_FEATURE_FLAG_FORCE_WAITER_THREAD=1 | 2 OK / 2 TIMEOUT (no change) |
| BUN_FEATURE_FLAG_DISABLE_IPV6=1 | 2 TIMEOUT (no help) |
| BUN_FEATURE_FLAG_DISABLE_DNS_CACHE=1 | 1 OK / 2 TIMEOUT (no help) |
| BUN_CONFIG_MAX_HTTP_REQUESTS=1 | 2 TIMEOUT (no help) |
| BUN_CONFIG_HTTP_RETRY_COUNT=0 | 1 OK / 1 TIMEOUT (no change) |
7. No bundled-JS escape hatch in 2.1.113+ — the npm package's cli-wrapper.cjs only spawnSyncs the same native binary; there is no JS code path and no CLAUDE_CODE_USE_JS_BUILD flag.
Suggested fix direction
- Diff the linux-x64 vs linux-arm64 Bun build pipelines for fetch / proxy tunneling
- Bisect Bun versions between the last known-good Claude Code release and the linux-x64 native build
- Provide an
CLAUDE_CODE_USE_JS_BUILD=1(or equivalent) escape hatch for affected users until the Bun fix lands
Repro
# On any linux-x64 host behind an HTTP CONNECT proxy:
curl -fsSL https://claude.ai/install.sh | bash -s -- 2.1.114
# (or: npm i -g @anthropic-ai/claude-code@2.1.114)
# Configure proxy in ~/.claude/settings.json `env` block (or just export HTTPS_PROXY).
for i in 1 2 3 4 5 6 7 8 9 10; do
timeout 45 claude -p --dangerously-skip-permissions --output-format stream-json \
--model claude-haiku-4-5-20251001 'Respond with only the word ok' \
> /dev/null 2>&1 && echo "$i OK" || echo "$i TIMEOUT"
done
Expect ~75 % TIMEOUT on linux-x64. On linux-arm64 or 2.1.112 expect 0% TIMEOUT.
---
Bug #1 (cascading) — settings.json.env strips HTTP(S)_PROXY and NO_PROXY from spawned subprocess env
Symptom
In ~/.claude/settings.json's env block, set 22 variables. From a Claude session, run Bash tool: printenv. The subprocess inherits 19 of the 22. The 3 missing keys, all in upper- and lowercase = 6 strings, are exactly:
HTTPS_PROXY, HTTP_PROXY, NO_PROXY,
https_proxy, http_proxy, no_proxy
ALL_PROXY / all_proxy are passed through normally. So is every non-proxy variable (CLAUDE_*, ANTHROPIC_*, OTEL_*, COLORTERM, BASH_DEFAULT_TIMEOUT_MS, DISABLE_AUTOUPDATER, etc.).
Evidence
The keys ARE loaded by Claude:
CA certs: Config fallback - globalEnv keys: ,
settingsEnv keys: ...,HTTPS_PROXY,HTTP_PROXY,ALL_PROXY,
https_proxy,http_proxy,all_proxy,NO_PROXY,no_proxy,...
But by the time a Bash tool subprocess is spawned, the 6 proxy keys (HTTPS/HTTP/NO, both cases) are gone, while ALL_PROXY survives. Workaround: export the 6 keys in the launcher shell — they then propagate normally — confirming the strip happens specifically in the settings.json → spawn env path, not in the runtime's general inheritance logic.
Suggested fix direction
Audit the env-merge logic between settings.json loading and child_process.spawn. Likely a leftover proxy-agent allow/denylist that filters HTTP/HTTPS/NO_PROXY but not ALL_PROXY. Either remove the filter or document it.
Minimal repro
// ~/.claude/settings.json
{
"env": {
"HTTPS_PROXY": "http://example:8080",
"HTTP_PROXY": "http://example:8080",
"NO_PROXY": "localhost",
"ALL_PROXY": "http://example:8080",
"FOO_BAR": "visible"
}
}
In the REPL, ask Claude to run:
printenv | grep -iE '^(https?_proxy|no_proxy|all_proxy|foo_bar)='
Expected: 5 lines. Actual: only ALL_PROXY / all_proxy / FOO_BAR.
---
Bug #2 (cascading) — OTEL_SDK_DISABLED=true does not stop OTEL exporter from opening connections
Symptom
settings.json.env.OTEL_SDK_DISABLED = "true" is loaded (visible in settingsEnv keys). Claude logs [3P telemetry] isTelemetryEnabled=false. But the OTEL exporter still opens TCP connections and times out:
[ERROR] [3P telemetry] OTEL diag error: {
"message":"Operation timed out.",
"sourceURL":"/$bunfs/root/src/entrypoints/cli.js",
"line":"421","column":"107499"
}
Repeats every ~40 s.
ss -tnp while the process is hung shows ≥3 ESTAB TCP connections from the claude pid to the proxy — the OTEL SDK isn't disabled at the network-init layer, only at the application-emit layer.
Suggested fix direction
Short-circuit OTEL exporter creation entirely when OTEL_SDK_DISABLED=true is set, before any socket open. (Currently it appears to create the exporter and only the emit path is gated.)
---
Bug #3 (cascading) — showSetupScreens() blocks for 400+ seconds on non-essential network calls
Symptom
UI sits frozen at the login / setup screen with no feedback for 6 minutes 40 seconds. The --debug log proves it's not a deadlock — it's a await on non-essential outbound HTTPS that times out and is internally retried.
Hard evidence (full log timestamps from one session)
01:31:21.521 [DEBUG] [STARTUP] Running showSetupScreens()...
01:31:21.582 [DEBUG] [Perfetto] initializePerfettoTracing called
01:31:21.582 [DEBUG] [3P telemetry] isTelemetryEnabled=false
01:31:21.588 [DEBUG] DECSTBM: gated
← UI frozen here
01:32:01.523 [ERROR] [3P telemetry] OTEL diag error: Operation timed out
← still frozen
01:38:02.117 [DEBUG] [STARTUP] showSetupScreens() completed in 400595ms
01:38:02.119 [DEBUG] [API:auth] OAuth token check starting
01:38:42.721 [ERROR] [3P telemetry] OTEL diag error: Operation timed out ← still retrying after REPL is up
Process state during the hang:
/proc/<pid>/status: State: S (sleeping), Threads: 6
/proc/<pid>/wchan: ep_poll
ss -tnp -- pid filter:
ESTAB ... -> proxy:49998 fd=18
ESTAB ... -> proxy:49998 fd=17
ESTAB ... -> proxy:49998 fd=19
3 TCP connections established (so this is not a SYN failure — TCP handshake completed) but the upper layer is waiting on responses that never arrive within the implicit timeout, and the wait is effectively unbounded.
Suggested fix direction
showSetupScreens()must notawaitnon-essential network. Render the UI immediately; let telemetry / Statsig / autoupdate run fire-and-forget in the background.- Cap any startup-path non-essential outbound at a tight (≤ 5 s) timeout.
- Provide a single
kill switchenv var that disables all non-essential outbound at startup, properly honored at the network-init layer (see Bug #2).
---
Why the four bugs likely share one root
- Bug #4 is the underlying race in Bun's linux-x64 fetch through HTTP CONNECT.
- Bug #3's intermittency matches Bug #4's intermittency exactly — sometimes the startup
awaitreturns fast (TLS race wins), sometimes it doesn't (and you wait 40 s ×N). - Bug #2 is the "isTelemetryEnabled=false but exporter still talks" mismatch — a flag layered above the network init, which only ever matters because Bug #4 makes that network init slow.
- Bug #1 is most plausibly an artifact of Bun's internal "proxy agent injection" — it consumes
HTTPS_PROXY/HTTP_PROXY/NO_PROXYfrom the env, applies them to its own internal HTTP agent, and forgets to put them back when spawning child processes.ALL_PROXY(which Bun's fetch arguably should also honor — see #14165) survives because nothing consumes it.
Fixing Bug #4 would dramatically improve user experience even if the other three remain; fixing all four restores parity with the 2.1.112 / arm64 baseline.
---
Workaround
npm i -g @anthropic-ai/claude-code@2.1.112
The bundled-JS 2.1.112 is 10/10 reliable on the same broken host. That's what we've fallen back to. Affected population: any x86_64 Linux user behind an HTTP CONNECT proxy (very common in enterprise deployments) on Claude Code ≥ 2.1.113.
---
Happy to attach raw strace logs, pcap captures, full --debug logs (showing the 400-second showSetupScreens hang and the 30-second Slow first byte warnings), and /proc/<pid>/{status,wchan,task} snapshots on request.
Showing cached comments. Read the full discussion on GitHub ↗
11 Comments
Follow-up: this looks like part of a wider pattern —
settings.jsonenvblock (and other env inputs) are not consistently honored after the v2.1.113 native-runtime switch.A few related reports that, taken together, suggest the env-propagation path was not fully ported when the runtime changed from Node.js to the new native binary:
ANTHROPIC_DEFAULT_*_MODELfromsettings.jsonsilently stripped under Desktop'sPROVIDER_MANAGED_BY_HOST. Same shape: env field set insettings.json, runtime ignores it.modelsetting insettings.jsonnot respected at session start. Anothersettings.jsonfield not being honored on 2.1.113.On our side (the original report), we tried adding the following to
~/.claude/settings.jsonenvto rule out telemetry/non-essential traffic as the proxy hang trigger:None of them changed observable behavior on 2.1.113 — startup hangs and WebFetch/WebSearch truncations continued at the same rate. On 2.1.112 (the last bundled-JS build) the same env block works as documented.
This makes us suspect the native binary's env-loading path from
settings.json.envis incomplete — at minimum theseDISABLE_*switches andHTTPS_PROXY/HTTP_PROXYaren't reaching whichever HTTP client the binary uses for the affected code paths.Concrete ask: please verify the
settings.json→env→ runtime path end-to-end on the new native binary, with particular attention to:HTTPS_PROXY,HTTP_PROXY,ALL_PROXY,NO_PROXYand lowercase variants)DISABLE_*/CLAUDE_CODE_DISABLE_*familyThanks!
Thanks for reporting. one note. for future issues please do not include multiple issues in the same report even if you believe they are originating from the same source. it makes state tracking much harder.
I have a fix landing for Bug #2.
for the others, i will need more info. Please use
/feedbackand share the link, this would give me the full debug-log timeline (Bug #3), the exact Bash tool input/output (Bug #1), and the API request timing (Bug #4).@mhegazy Thanks for the triage.
Feedback ID:
5c1290c0-5456-4a59-aaf9-9b3df06a6c212.1.118.a9dapi.anthropic.com:443This single session captures three symptoms of what we believe is the same Bun fetch/socket race:
1. Startup blocks 400s inside
showSetupScreens()From the
--debuglog, contiguous lines 48–67 (nothing in between):Post-startup, OTEL diag fires at a consistent native frame:
OTEL_SDK_DISABLED=trueis set;[3P telemetry] isTelemetryEnabled=falseconfirms the flag parses — yet something on that path still opens a socket and blocks for ~400s.2. WebFetch: one of N parallel calls stalls while siblings succeed
User fired 4 parallel WebFetch calls. 3 returned in 2–3s. One hung for 44.7s until Esc:
[onCancel]arrives 3ms beforetool_dispatch_end error— the cancel path released the socket, not a natural fetch completion/timeout.3.
/feedbacksubmission itself hit the same raceRight after #2, while uploading this report:
It eventually recovered and produced the Feedback ID above — but a 30s+ stall on a third, unrelated code path (feedback upload vs tool-use vs OTEL exporter) reinforces the common factor: Bun's fetch/socket layer on linux-x64 behind HTTP CONNECT, not any specific feature.
See the follow-up comment for a stricter reproduction of symptom #2 (cancel truly not honored) from a second machine.
Follow-up on a stricter form of WebFetch cancel-not-honored, from a second machine:
Feedback ID:
bd8b02c5-8222-428c-a26e-20ff9995f4ea2.1.118.c75(different 2.1.118 build hash — same symptom)User pressed Esc three times across three different
streamModevalues. The underlying Bun fetch was never torn down — log ends without adispatch_endfor that toolUseId:Three different
[onCancel] streamMode=values confirm the UI cancel reached the orchestrator in all three UI states (tool-use→thinking→requesting), but the underlying fetch/socket never unblocked. This session had to file/feedbackwith the dead WebFetch still hanging in the background.Together with the primary comment: two different 2.1.118 build hashes (
a9dandc75), two different kernels (6.14.0-oemand6.8.0-generic), identical symptoms — rules out build-specific or kernel-specific causes, leaves the Bun runtime + linux-x64 + HTTP CONNECT intersection.Already ruled out (per OP): network (curl/tcpdump OK via same proxy), packaging (identical BuildID across distribution channels), ARM64 (10/10 OK same settings), CPU count (8-core reporter identical),
strace(5/5 OK under strace, classic async I/O race cure), 7 Bun tuning env flags (no effect).Happy to run targeted traces if an instrumented build is cut.
Update — minimal repro isolated to a TCP-level pattern in CONNECT 200 response handling.
We narrowed this down to a single behavior: Bun-x64 fetch hangs when the upstream HTTP CONNECT proxy delivers
HTTP/1.1 200 OK\r\n\r\nacross two TCP segments instead of one.No exotic transport involved — reproduced with a Mac on the same LAN running a 50-line Python
socketproxy. Two run modes, only difference is onesendallvs two consecutivesendalls for the CONNECT 200 line.Repro setup
claude2.1.119 (Bun-x64 native build,cc_version: 2.1.118.c75series)api.anthropic.com:443claude -p --dangerously-skip-permissions --verbose --output-format stream-json --model claude-haiku-4-5-20251001 'Respond with only the word ok', with a 45stimeoutwrapper, repeated 5×.Python CONNECT proxy (drop in and run)
Results (5 trials each, exact same network, exact same destination, exact same Bun binary)
| Proxy mode | CONNECT 200 wire format | Outcome |
|---|---|---|
|
--mode normal| one TCP segment:HTTP/1.1 200 OK\r\n\r\n(19 bytes) | 5/5 OK, 10-15s each ||
--mode split| two TCP segments:HTTP/1.1 200 OK\r\n(17 bytes) +\r\n(2 bytes) | 1/5 OK, 4/5 TIMEOUT at 45s; the one OK trial took 31s |Hypothesis
Bun-x64's HTTP CONNECT response parser appears to commit to "tunnel established → switch to TLS passthrough" as soon as it sees the status line + first CRLF, without waiting for the empty-line terminator (the second
\r\n). When the second\r\narrives in a separate TCP read, those 2 bytes are consumed as if they were the start of the TLS ServerHello, the TLS record framing is then permanently misaligned by 2 bytes, and the HTTPS/2 stream can never reachEND_STREAM/GOAWAY. The fetch hangs until external timeout/cancel.This explains all of the previously-reported symptoms in this issue, including the WebFetch "cancel not honored" cases — once the TLS framing is corrupted, even an
AbortSignal/socket.destroy()on Bun's side can't reach a coherent "done" state, because the application layer is still waiting for bytes that will never parse.Why it appears intermittent on real proxies
Most production HTTP CONNECT proxies (squid, tinyproxy, Tailscale's built-in CONNECT proxy, etc.) write the entire response with a single
write(2)and the kernel sends one TCP segment, so they never trigger this. Some proxy implementations — particularly transport-converting proxies that bridge TCP↔QUIC or TCP↔WebSocket — naturally split the response across packet boundaries, so they trigger it ~100% of the time. ARM64 Bun on the same network does not appear to hit this, suggesting the parser bug is specific to the x86_64 native build (or its IO read sizing).Note
If a follow-up trace under an instrumented Bun build would help, happy to run it on the same setup. The repro takes < 1 minute end-to-end.
Cross-architecture control: aarch64 is unaffected.
Ran the same
--mode splitPython CONNECT proxy from the previous comment, against an aarch64 host on the same LAN, talking to the same destination over the same Tailscale link. The only variable changed is the architecture of theclaudebinary on the client side.| Host | Arch | claude version | Same
--mode splitproxy | Result ||---|---|---|---|---|
| Linux x86_64, kernel 6.8.0-107-generic | x86_64 | 2.1.119 | (same Python script, same Tailscale link, same upstream) | 1/5 OK, 4/5 TIMEOUT at 45s |
| Linux aarch64, kernel 6.14.0-1015-nvidia | aarch64 | 2.1.118 | same | 5/5 OK, 5-7s each |
Same 5-trial loop, same prompt, same model (
claude-haiku-4-5-20251001), same--output-format stream-json --verbose. Only the architecture of the localclaudebinary differs.This narrows it further: the buggy CONNECT-200 read path is in the x86_64 native build specifically, not in shared cross-platform code. Likely candidates would be x86_64-only fast paths in Bun's HTTP/socket reader (e.g. SIMD scan over the response head, or x86_64-tuned recv buffer sizing that takes a different branch when the first read returns ≤ a threshold of bytes).
Hopefully helpful for narrowing the search; happy to run any further targeted comparisons on either build.
Confirmed root cause + working sender-side workaround.
Filed an upstream issue and PR on the proxy side that triggered this in our environment:
client/http: CONNECT 200 reply is split across 2 TCP segments, breaking framing-sensitive clients (e.g. Bun x86_64 / Claude Code)conn.Writeso the kernel emits a single TCP segmentThe hysteria-side trigger turns out to be Go stdlib
net/http.Response.Write— for aContentLength=-1headerless response it issues two separate underlying writes (status line, then trailing CRLF), and Go defaults*net.TCPConntoTCP_NODELAY=true, so the bytes leave as two TCP segments. This matches the wire pattern the Python--mode splitreproducer in comment 4319520748 was simulating.End-to-end verification on the same machine (Ubuntu 24.04.3 x86_64, kernel 6.8.0-107, Claude Code 2.1.119):
| hysteria build | claude
-p5-trial result ||---|---|
| v2.8.1 stock | 1/5 OK, 4/5 timeout at 45s |
| v2.8.1 + apernet/hysteria#1554 | 5/5 OK, 9–15s each |
tcpdump -i loon the local proxy port confirms the 200 response is now a single 19-byte TCP segment (was 17 + 2 before).This is a sender-side workaround that unblocks anyone hitting this through hysteria2; it does not address the underlying Bun-x86_64 CONNECT/TLS framing fragility, which still affects any other CONNECT proxy that happens to split the response (transport-converting proxies, some QUIC/WebSocket bridges, etc.). Posting in case it helps narrow the search on the Bun side: the fragile path is "first segment ends exactly at status-line
\r\n, second segment is just the empty-line\r\n" — Bun-aarch64 handles this fine, only Bun-x86_64 misframes.Happy to run any further targeted comparisons against either build.
I'm not sure if this is related but I'm not seeing my HTTP_PROXY and HTTPS_PROXY env vars reliably passed through claude into Bash subprocesses like I used to on windows. I tried setting 'settings.enableWeakerNetworkIsolation' but that only let HTTP_PROXY pass through, not HTTPS_PROXY. I can't use settings.json since my port changes per claude instance.
Workaround confirmed on aarch64 / claude-code 2.1.131 — rebuild hysteria with apernet/hysteria#1554
Adding a data point that the architecture profile has shifted on recent claude-code releases:
| host | claude-code | local proxy | result with stock hysteria |
|---|---|---|---|
| Raspberry Pi 4 Model B Rev 1.5, aarch64, Ubuntu 24.04.4 LTS, kernel 6.8.0-1053-raspi | 2.1.131 (Bun native) | hysteria2 client v2.9.1, HTTP listener | TLS handshake hang / fetch timeout — same symptom previously reported only on x86_64 |
So the earlier "Bun-aarch64 is not affected" cross-arch result from the 2.1.118/2.1.119 era no longer holds on 2.1.131. Whether the cause is a Bun upgrade or something else in the native build, I haven't dug in — but anyone on ARM seeing the same hangs should know the workaround tree is now the same as for x86_64.
Sender-side fix that I just verified works end-to-end (system has Go, native build on the Pi):
After swap-in, claude operations through the same proxy went from intermittent hangs to clean. Until either the Bun-side parser fix lands here or apernet/hysteria#1554 merges upstream, this is the cleanest workaround for ARM users behind hysteria2.
Closing for now — inactive for too long. Please open a new issue if this is still relevant.