Interactive mode exits immediately (exit 0) on Linux kernel 4.18 (Kubernetes/RHEL 8)
Description
Claude Code interactive mode starts, renders the TUI welcome screen with REPL prompt (❯), then immediately exits with code 0 within ~1 second. Non-interactive mode (claude -p "prompt") works correctly.
Environment
- Claude Code: v2.1.70 (also reproduced on v2.1.58)
- OS: Ubuntu 24.04.3 LTS container on Kubernetes
- Host Kernel:
4.18.0-305.131.1.el8_4.x86_64(RHEL/CentOS 8) - Platform: TWCC (Taiwan Computing Cloud) — HPC/GPU cluster
- Memory: 754GB (not OOM)
- glibc: 2.39
- TTY: Valid
/dev/pts/Xvia tmux, terminal size 36×120
Steps to Reproduce
- SSH into a Kubernetes pod running on a RHEL 8 host (kernel 4.18)
- Start
tmux(or any terminal with a valid PTY) - Run
claudeorclaude --dangerously-skip-permissions - Complete the trust prompt (select "Yes, I trust this folder")
- Result: Welcome screen renders, REPL prompt appears, process exits with code 0
Key Findings
| Test | Result |
|------|--------|
| claude --version | Works |
| claude -p "hello" | Works |
| claude (interactive) | Exits immediately after REPL renders |
| Trust prompt | Stays alive (blocking input) |
| After trust confirmation | Exits within ~1s |
| Node.js stdin.resume() on same system | Keeps event loop alive correctly |
strace evidence
io_uring_setup(syscall 425) returns ENOSYS — kernel 4.18 has stubs but no implementation (io_uring was introduced in kernel 5.1)- Bun falls back to epoll, but
epoll_waitruns only 1 time before event loop drains - Main process never reads from stdin (fd 0) — stdin watcher appears unregistered
- Process sends SIGPWR to itself (Bun internal signal), removes all epoll watchers, then
exit_group(0)
Debug log
[REPL:mount] REPL mounted, disabled=false
performStartupChecks called
AutoUpdaterWrapper: Installation type: native
Ripgrep first use test: PASSED
REPL mounts successfully, no errors logged, then process exits silently.
What was ruled out
- PTY/terminal issues (valid PTY, correct TERM, correct dimensions)
- VS Code shell integration (reproduced in plain tmux)
- Auth/OAuth (token valid,
--printmode works) - Environment variables (reproduced with
env -iclean env) - Auto-update (
CLAUDE_CODE_DISABLE_AUTOUPDATE=1— same result) - Multiple versions (v2.1.58 and v2.1.70)
expectwrapper with separate PTY — same exitBUN_FEATURE_FLAG_FORCE_WAITER_THREAD=1— no effect
Full Diagnostic Report
Gist with debug logs, strace output, and environment info:
https://gist.github.com/thc1006/2bb7392607c524df67ecd24cae98bc67
Hypothesis
Bun runtime's event loop does not properly maintain stdin watchers when io_uring_setup returns ENOSYS on kernels < 5.1. The epoll fallback appears incomplete — the event loop determines there are no active handles after one iteration and drains, causing a clean exit.
Impact
Kernel 4.18 (RHEL/CentOS 8) is widely used in enterprise HPC and Kubernetes environments. Interactive mode is unusable on these systems. Only claude -p (non-interactive) works.
This issue has 6 comments on GitHub. Read the full discussion on GitHub ↗