Claude Desktop leaks pty (ptmx) fds -> system-wide pty exhaustion (terminals die with 'forkpty: Device not configured')
Environment
- Claude Desktop: 1.11187.4
- claude-code: 2.1.165
- macOS: 26.3 (25D125), Mac16,7 (Apple Silicon)
Summary
The Claude Desktop main process (/Applications/Claude.app/Contents/MacOS/Claude) accumulates pty master file descriptors (/dev/ptmx) without releasing them. Over a ~2-hour session it leaked to 509 open ptmx handles, hitting the macOS limit kern.tty.ptmx_max=511. Once exhausted, no application on the machine can allocate a new pty — every terminal (Terminal.app, iTerm2) fails to start a shell and the window closes instantly; tmux/script also fail.
Evidence
$ lsof -n /dev/ptmx | awk 'NR>1{print $2}' | sort | uniq -c | sort -rn
509 4065 # /Applications/Claude.app/Contents/MacOS/Claude (single main process)
1 16467 # VS Code
$ sysctl kern.tty.ptmx_max
kern.tty.ptmx_max: 511
$ python3 -c "import pty; pty.openpty()"
OSError: out of pty devices
# Terminal.app window content right before it closes:
[forkpty: Device not configured]
All 509 handles are held by the single main process (pid 4065), not spread across child session processes — killing individual claude-code subprocesses does not free them; only quitting the main app does. This points to a leak in the parent process's pty management, not per-session cleanup.
Reproduction
- Run Claude Desktop with Claude Code executing shell/Bash tools over a long session (multiple sessions / agents).
- Each tool invocation opens a pty whose master fd is never closed after the child exits.
- Leaked ptmx handles climb to the
ptmx_maxceiling (511) over a few hours. - Open Terminal.app / iTerm2 -> window opens then closes instantly (forkpty fails).
Impact
System-wide: all terminals on the machine become unusable, not just Claude's. The symptom is highly misleading — it looks like a zsh/tmux startup crash, which makes it very hard to diagnose.
Workaround
- Temporary:
sudo sysctl -w kern.tty.ptmx_max=999(raises the ceiling above the leak; lost on reboot; 999 is the macOS hard cap). - Real recovery: fully quit & relaunch Claude Desktop to release all leaked handles.
Expected
pty master fds should be closed when the corresponding tool invocation / child process ends.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗