Claude Desktop leaks pty devices (node-pty masters never released) → macOS hits kern.tty.ptmx_max, no terminal can spawn

Open 💬 0 comments Opened Jun 23, 2026 by inforeole

Summary

The Claude Desktop app (Electron main process) leaks pty devices: every Claude Code session / agent / background shell it spawns in local-agent mode opens a pseudo-terminal pair (/dev/ptmx master + /dev/ttysNNN slave) that is never released when the session ends. The masters accumulate on the long-lived Claude.app process and grow monotonically over the app's lifetime.

On macOS the kernel caps the total at kern.tty.ptmx_max (default 511). Once that ceiling is reached, no process on the machine can allocate a new pty — opening any new terminal (Ghostty, Terminal.app, zellij, even Claude Code itself) fails with:

your system cannot allocate any more pty devices.

A reboot or quitting the app clears it, but the leak then starts over.

Environment

  • macOS 26.4.1 (Apple M5, 32 GB)
  • Claude Desktop app 1.14271.0
  • Bundled Claude Code 2.1.181
  • kern.tty.ptmx_max = 511 (default)

Evidence (measured)

Counting pty masters held per process with lsof -p <pid> | grep -c ptmx, and total allocated pairs with ls /dev/ttys* | wc -l:

| Moment | Total pty (/dev/ttys*) | Held by Claude.app (PID, PPID 1) |
|---|---|---|
| Just after reboot | 68 / 511 | 48 |
| ~2 h uptime | — | 43–48 |
| ~1 day uptime | 232 / 511 | 212 |
| Immediately after Cmd+Q on the app | 20 / 511 | 0 (process gone) |

The holder is the Electron main process (/Applications/Claude.app/Contents/MacOS/Claude, PPID 1), not the child claude CLI processes — which points at the app's pty management layer (node-pty in Electron) not reaping masters when an agent/terminal session terminates.

Growth is linear with uptime and never decreases while the app is running. 48 → 212 in ~24 h on a normal dev day.

Reproduction

  1. Open Claude Desktop, run several Claude Code sessions / agents over a day (local-agent mode), closing them normally.
  2. Periodically measure: ls /dev/ttys* | wc -l and lsof -p $(pgrep -f 'Claude.app/Contents/MacOS/Claude$') | grep -c ptmx.
  3. Observe the Claude.app ptmx count climb monotonically and never drop when sessions end.
  4. Eventually total pty hits kern.tty.ptmx_max (511) → any new terminal anywhere on the system fails with "cannot allocate any more pty devices".

Impact

  • Not just Claude: it starves the entire machine of pty devices. The first victim is usually an unrelated terminal emulator, making the root cause non-obvious.
  • Heavy users (many agent sessions / day) hit the 511 ceiling within ~2 days of uptime.

Expected

pty pairs should be released when the session/shell that owns them terminates (as a normal terminal emulator does on tab close).

Workaround

Cmd+Q on Claude Desktop releases all leaked pty at once (212 → 0 in our case). Reboot does the same. Raising kern.tty.ptmx_max only delays the ceiling.

View original on GitHub ↗