[BUG] claude auth startup spins at 100% CPU indefinitely with no timeout (Bun runtime) — `--version` unaffected, CLAUDE_CODE_OAUTH_TOKEN suspected trigger
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
claude startup can spin at a sustained 100% CPU with no timeout or upper bound. This is not slow network, not one-time indexing, and not I/O wait:
- Not slow network/API latency —
strace -e trace=network,file,processshows zero network syscalls after startup begins; it never even attempts a connection. - Not first-run indexing — reproduced repeatedly across fresh installs, with
~/.claude/fully deleted before each test. - Not I/O wait — confirmed via
top -H: 0% iowait, 99.9% user CPU, sustained and climbing every sample.
Reproduces identically across claude, claude auth, and claude auth login --token <token> — all hang. claude --version returns instantly, so this is specific to code paths reached only when going past version/arg parsing into auth/startup init.
What Should Happen?
Startup logic — particularly whatever handles OAuth token processing on launch (see suspected trigger below) — should have a bounded retry count or timeout, and should fail visibly with an error rather than spinning indefinitely with no user-facing feedback.
Error Messages/Logs
None produced — the process gives no output, no error, and never exits on its own.
CPU evidence, `top -H -b -n 5 -d 1 -p <pid>` (5 consecutive samples, 1s apart):
PID ... %CPU TIME+ COMMAND
<pid> ... 99.9 6:26.75 claude <- climbing every sample: 6:26 → 6:27 → 6:28 → 6:29 → 6:30
... ... 0.0 0:00.00 mi-scavenger (idle worker thread)
... ... 0.0 0:00.00 Bun Pool 0 (idle worker thread)
... ... 0.0 0:00.00 Bun Pool 1 (idle worker thread)
Only the main thread is active; all worker/pool threads sit idle in `futex_do_wait`. This is a live, ongoing single-thread spin, not a one-off spike.
Steps to Reproduce
- On the affected environment, ensure
CLAUDE_CODE_OAUTH_TOKENis set in the environment (see suspected trigger). - Delete
~/.claude/if present, to rule out local state. - Run
claude auth(or plainclaude, orclaude auth login --token <token>). - Observe: process hangs indefinitely, CPU pegs at ~100% on the main thread, no output ever appears.
- Confirm via
top -H -p <pid>: CPU time climbs continuously with no plateau.
Claude Model
None
=> missing in the bug report select box a different platform:
_process never reached model selection; hung during startup before that step was ever reached_
Is this a regression?
I don't know
Last Working Version
unknown / first run on this env
Claude Code Version
2.1.233
Platform
Anthropic API
=> missing in the bug report select box a different platform:
_Claude Pro/Max subscription OAuth token_ (via CLAUDE_CODE_OAUTH_TOKEN)
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Other
=> missing in the bug report select box a different platform:
_ssh console / bash_
Additional Information
Companion issue: #87553 — SIGINT/Ctrl+C is also completely unresponsive during this same hang. Filed separately since the signal-handling gap and the CPU-spin trigger are independently confirmable bugs, but they were discovered together on the same host and likely share remediation priority.
Runtime note: the claude binary here is a Bun-compiled executable (confirmed via live thread names mi-scavenger, Bun Pool 0/Bun Pool 1), installed under an nvm-managed Node v24.19.0 bin path — Node itself is not the runtime actually executing.
Config ruled out as cause: ~/.claude/ was fully deleted before this test (ls -la ~/.claude/, du -sh ~/.claude both empty/absent).
Suspected trigger: CLAUDE_CODE_OAUTH_TOKEN is present in the environment during every repro attempt. Testing is in progress on whether unset CLAUDE_CODE_OAUTH_TOKEN; claude auth still hangs — will update this issue with the result. If unsetting it resolves the hang, that strongly implicates OAuth token parsing/validation on startup as the spinning code path.
Related, not a duplicate: #75561 (claude --resume hangs on account-level connector discovery) is the same class of bug — an unbounded startup hang with no timeout — but a different subsystem and mechanism (network read stall via kevent64, vs. our confirmed pure CPU spin with zero network activity). Flagging as a pattern worth maintainers' attention across both: startup-path calls in general appear to lack bounded timeouts.
Explicitly not related: #80661 (Hyper-V claude --version V8 HeapHelper livelock via sched_yield) differs on every relevant axis — it hangs on --version specifically (ours doesn't hang there at all), it's Node/V8 (ours is Bun), and it's Hyper-V-specific paravirtualized clocksource sensitivity (ours is KVM, unrelated clocksource mechanism). Not the same bug; noting explicitly to prevent incorrect merging.
Happy to provide full untruncated strace output, /proc/<pid> captures, or a minimal repro on request.
4 Comments
Update: tested with
CLAUDE_CODE_OAUTH_TOKENunset entirely —claude authstill hangs identically. This rules out the OAuth token env var as the trigger; the suspected-trigger note in the original report was incorrect. Root cause is still open — happens regardless of auth-token presence, so it's something else in startup, not token parsing/validation as originally hypothesized.Update: further isolation testing, all on the same host.
CLAUDE_CODE_OAUTH_TOKENunset entirely →claude authstill hangs identically. Rules out the OAuth-token env var as the trigger (see previous comment — correcting the original "suspected trigger" hypothesis).npm install -g @anthropic-ai/claude-code@latestsilently skipped theinstall.cjspostinstall step due to anallow-scriptspolicy on this host (npm warn allow-scripts ... not yet covered by allowScripts). Re-ran with--allow-scripts=@anthropic-ai/claude-codeso postinstall actually completes. No change — 2.1.234 with postinstall properly run hangs identically (confirmed viatop -H: same 99.9%-CPU-on-main-thread, samemi-scavenger/Bun Pool 0/Bun Pool 1thread signature).2.1.233→ hangs (original report)2.1.234(npmlatest) → hangs identically2.1.226(npmstabletag) → hangs, but worse and different: evenclaude --versionhung here (never happened on 2.1.233/2.1.234), and the thread signature at the point of hang was different — only 2 threads present (main +mi-scavenger), noBun Poolworkers spawned yet, suggesting it stalls earlier in startup on this version. Possibly a distinct/additional bug rather than the same one; noting for the record but not pursuing further downgrades since it's strictly worse, not diagnostic.claude --versionresponds instantly there.Net effect: OAuth token, local config, and npm postinstall/allow-scripts are all ruled out. The hang reproduces across three separate versions with a consistent signature (except the 2.1.226 outlier above), which points away from a single-version regression and toward something more fundamental. Currently testing the native (non-npm) installer to rule out npm packaging/install-path issues entirely — will update with that result.
Update: significant new isolation, posting current state.
Native (non-npm) installer also hangs, ruling out npm/postinstall/allow-scripts as a category entirely, not just this one instance:
curl -fsSL https://claude.ai/install.sh | bash
This hung at the "Setting up Claude Code..." step, which appears to invoke the freshly-downloaded binary as part of its own setup — same failure class as everything else here.
Fresh, non-root user with a completely fresh nvm/npm install reproduces the identical hang. Created a brand-new user account, fresh nvm, fresh npm install -g @anthropic-ai/claude-code, no shared dotfiles/config/history with any previous test. claude still hangs identically: top -H shows the same signature as every prior test — main thread pegged at 99.9% CPU, mi-scavenger/Bun Pool 0/Bun Pool 1 idle. This rules out per-user configuration, shell state, or account-specific cruft as a factor.
Ruled out: security/monitoring software. ps aux shows no EDR/security agent (checked for falco, auditd-as-a-third-party-tool, CrowdStrike, SentinelOne, Wazuh, osquery, ClamAV, eBPF-based tools) — only the normal kernel [kauditd] thread present on any system with audit rules loaded. dmesg shows nothing relevant; the only recent entries are routine Docker container network interface churn (veth/bridge events from dockerd), unrelated to this bug.
Kernel version ruled out as the root cause — this is the important one. This host is a Proxmox/KVM guest. It was running Ubuntu 22.04 with this exact same issue; I upgraded to Ubuntu 26.04 yesterday specifically hoping a newer kernel/OS would resolve it. It didn't — same hang, same signature, on a completely different kernel major (26.04 now runs 7.0.0-29-generic, built July 2026; 22.04's kernel was materially older). Since the only constant across that upgrade is the underlying Proxmox/KVM hypervisor and virtual hardware (guest kernel, and by extension anything kernel-version-specific, changed completely), this points at the virtualization layer itself — CPU model/flags exposed to the guest, or the paravirtualized clocksource — rather than the guest kernel.
That's structurally the same category of bug as the already-confirmed #80661 (Hyper-V claude --version hang via V8/Bun startup thread-sync sensitivity to a paravirtualized clocksource), just a possible KVM/Proxmox-specific manifestation instead of Hyper-V. Currently testing the guest's clocksource (kvm-clock vs tsc) as the next specific hypothesis, mirroring the diagnostic that nailed down #80661 — will report the result.
Broader pattern worth flagging: this exact signature — Bun main-thread spin/livelock during startup, SIGINT/SIGTERM completely ineffective, only kill -9 works — has now been observed across Ubuntu 22.04, Ubuntu 26.04 (two different kernel majors, same physical host), and independently on macOS ARM64 in #18532. That platform diversity suggests the underlying bug may live in Bun's own thread-pool/mimalloc startup code (a race or livelock during mi-scavenger/Bun Pool initialization), with different environment factors (virtualized clocksource on Linux/KVM, something else on macOS) acting as different triggers for the same underlying runtime issue rather than fully independent bugs.
Will follow up with the clocksource test result.
Root cause found
After ~2 days of systematic elimination on this issue (see prior comments for the full trail: OS version, kernel version 7.0.0, npm vs. native installer, postinstall/allow-scripts, CLAUDE_CODE_OAUTH_TOKEN, per-user config, clocksource, RAM, ballooning, KSM, cgroup nesting/Docker isolation, and security/monitoring software — all ruled out), the actual trigger is the guest CPU type exposed by the hypervisor.
This host runs Proxmox VE 9.2.x (KVM) with real Intel CPUs underneath, but the VM's CPU type was set to kvm64 — QEMU's default, deliberately minimal baseline (pre-SSE4-era instruction set, chosen for maximum compatibility across arbitrary migration targets). That minimal feature set is what triggers the hang.
Fix confirmed: changing the VM's CPU type to x86-64-v3 (and separately confirmed x86-64-v4 also works) resolves the hang completely. Verified via multiple clean runs reaching full interactive startup — real TLS handshakes completing, actual API response data flowing, reaching the interactive theme-selection screen — not just a --version check.
qm set <vmid> --cpu x86-64-v3
qm stop <vmid>
qm start <vmid>
(Requires a full VM stop/start, not just a guest reboot — CPU type is read once at QEMU process launch.)
For anyone else hitting this on Proxmox/KVM: if your VM's CPU type is kvm64/qemu64 (or another pre-Haswell baseline) and claude hangs on startup with the signature described in this issue (99.9% CPU on the main thread, mi-scavenger/Bun Pool 0/Bun Pool 1 idle, unkillable via SIGINT), try bumping the CPU type to at least x86-64-v3. This is a portable, migration-safe fix (x86-64-v3 requires only Haswell-or-newer on the receiving host, not full host-passthrough pinning to exact silicon), so it's usable in production clusters, not just single-host debugging.
Not yet narrowed down: whether x86-64-v2/x86-64-v2-AES (a lower bar, useful for older hardware) also fixes it, or whether v3's AVX2/BMI/FMA/F16C additions specifically are required. Happy to test further if useful for triage.
For the Claude Code / Bun team: this strongly suggests a CPUID feature-detection routine somewhere in Bun's startup (possibly related to mi-scavenger/mimalloc initialization, or Bun's own thread-pool sizing logic, given the consistent thread signature across every failure mode we've seen) that doesn't gracefully handle a CPU lacking modern instruction-set extensions — spinning/livelocking instead of falling back to a slower code path or failing with a clear error. Given the cross-platform pattern already noted in this thread (same signature on macOS ARM64 in #18532), it may be worth checking whether that report's hardware also has some analogous "limited/unusual CPU feature exposure" angle, even though the specific mechanism there is licon, not x86 microarchitecture levels).