Idle session pins a CPU core: OTEL socket stuck in a zero-wait send() retry loop (~800K syscalls/s, 0 bytes sent)

Status Open
Reported on v2.1.299
Maintainer reply None cached
Activity 0 comments · opened Oct 15, 2026

What happens

An idle Claude Code session pins a CPU core at 100% and never recovers. It isn't working. It's retrying a failing send() about 800,000 times a second.

   send() fails (-1)
        │
        ▼
   "wait until writable"  ──►  kqueue: "writable now!"   (send buffer is empty)
        ▲                                 │
        └──────── retry same send() ◄─────┘

   ≈ 800,000×/sec  ·  0 bytes leave the machine  ·  never stops

| | Healthy session | Stuck session |
|---|---|---|
| CPU | ~2% | 95–130% |
| Syscalls / sec | ~400 | ~850,000 |
| CPU time | mostly user | 78 min system / 18 min user |
| Bytes sent on the socket | — | 0 (counters frozen) |

Root cause

The stuck socket is always the OTLP exporter's keep-alive HTTPS connection (OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf). The bundled Bun v1.4.3 flushes pending TLS bytes with ssl_drain_spill() → us_socket_raw_write():

int written = bsd_send(fd, data, length);   // -1 on error
if (written != length) {                    // -1 != length → true
    s->flags.last_write_failed = 1;
    us_internal_rearm_writable(s);          // "wake me when writable"
}
return written < 0 ? 0 : written;           // error becomes "0 bytes written"

A real error is handled like "buffer full, try later". The buffer is empty, so the socket is writable immediately. kqueue fires again at once, and the same failing send is retried forever. Nothing closes the socket or reports the error.

Evidence (macOS, offsets from 2.1.299)

  • sample: 81% of main-thread samples in __sendto

loop tick (0x7ed268) → us_internal_dispatch_ready_poll (0x7eeb00) → TLS on-writable / ssl_drain_spill (0x7ea984) → us_socket_raw_write (0x7f66f4) → send()

  • lskq: EVFILT_WRITE EV_ADD|EV_ONESHOT on the OTLP socket, status active+queued the instant it's added
  • netstat: socket ESTABLISHED, Send-Q 0, rx/tx counters frozen while send() runs ~10⁵–10⁶×/sec
  • Of 10 Claude Code processes on the machine, only the 2 holding an OTLP connection were spinning

When it happens

  • OTEL enabled: OTEL_LOGS_EXPORTER=otlp, OTEL_METRICS_EXPORTER=otlp, http/protobuf (pushed via org managed settings here)
  • Long-running sessions (seen at 16h and 21h), both CLI and Desktop
  • Every build from 2.1.295 to 2.1.301 ships Bun v1.4.3

Expected

To recover my pc

Not captured

The errno behind the first failed send(). SIP is on and the binary has hardened runtime, so it can't be traced without root.

Environment

macOS 27.0.1 (Apple Silicon) · Claude Code 2.1.299 (CLI), 2.1.295 (Desktop-embedded), 2.1.301 · Bun v1.4.3

View original on GitHub ↗