Skip to content

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

Open

Description

@omarmahamid

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:corebugSomething isn't workinghas reproHas detailed reproduction stepsperf:cpuplatform:macosIssue specifically occurs on macOS

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions