Desktop app SIGKILLs its own Claude Code workers on a healthy Mac, then blames endpoint security (gates on raw free pages, not memory pressure)
Summary
The desktop app SIGKILLs its own Claude Code worker processes on a healthy machine, and reports the cause to the user as "Blocked by endpoint security — ask your IT team to allowlist signing Team ID Q6L2SF6YDW."
There is no endpoint-security software on this machine. The kills correlate with sys_free_raw (raw free pages) falling below ~800 MB — a metric that is near-zero on every healthy macOS system by design, because macOS deliberately uses idle RAM for cache and compressed pages.
Two bugs:
- The gate uses the wrong memory metric. Low raw-free memory is the normal steady state on macOS, not a distress signal. The OS exposes
kern.memorystatus_vm_pressure_levelfor exactly this purpose. - The error message misattributes the cause, sending users to their IT department for a problem the app created. On a personal Mac with no MDM there is nothing to allowlist.
Environment
- Claude desktop 1.37937.3 (also observed on 1.30096.5 and 1.32885.1 — this is not new)
- Claude Code 2.1.246
- macOS 26.6.1, Apple M4, 16 GB RAM, no MDM, no EDR, no MDM profiles
Evidence
The machine is not under memory pressure at any point:
| macOS metric | value |
|---|---|
| kern.memorystatus_vm_pressure_level | 1 (normal) |
| vm.swapusage used | 0.00 MB |
| memory_pressure "system-wide memory free" | 78% |
| Jetsam reports in /Library/Logs/DiagnosticReports | 0, ever |
| log show --predicate 'process == "kernel"' around each kill, matching kill/jetsam/memorystatus | 0 lines |
No endpoint-security software exists to have done it:
| check | result |
|---|---|
| systemextensionsctl list — endpoint security extensions | 0 |
| /Library/LaunchDaemons/ | empty |
| EDR processes (CrowdStrike, SentinelOne, Sophos, Defender, Jamf, Santa…) | 0 running |
| unified-log endpoint-security events in each kill window | 0 |
The app's own log shows it doing the killing. Every kill is recorded by the app with its own error class:
[error] Session <id> query error: Claude Code process terminated by signal SIGKILL
{ errorClass: 'process_killed_by_signal', signal: 'SIGKILL',
stack: 'Error: ... at vq.getProcessExitError (…/app.asar/.vite/build/index.chunk-*.js) …' }
The correlation — 4 kills in one day vs 211 [process-memory] readings
| kill time | tree_rss_sum | children | sys_free_raw | sys_free |
|---|---|---|---|---|
| 11:54:35 | 8928 MB | 142 | 63 MB | 2174 MB |
| 11:59:57 | 4419 MB | 29 | 350 MB | 3037 MB |
| 12:07:03 | 4692 MB | 39 | 697 MB | 3360 MB |
| 15:04:18 | 4195 MB | 26 | 268 MB | 4530 MB |
- Tree size does not discriminate — 4.2–8.9 GB and 26–142 children across the four kills.
sys_free_rawdoes — every kill occurred below 800 MB; not one occurred above it (0 of 30 readings ≥800 MB were followed by a kill within 60 s).- It is a precondition, not a trigger: 177 readings below 800 MB were not followed by a kill.
Note the 11:54 row: the app logged sys_free=2174MB alongside sys_free_raw=63MB at the same instant. It appears to gate on the raw figure.
Why this is the wrong metric
macOS keeps raw free pages near zero on purpose — unused RAM is used for file cache and compressed memory, and released on demand. A machine with 63 MB "free", 0 bytes of swap, and pressure level 1 is healthy. Gating on that figure means the app will reap workers on any well-utilised Mac, which is what happens here: the kills land while the OS itself reports normal pressure and has never once needed to jetsam a process.
Impact
- Long-running agent work is destroyed mid-flight, repeatedly (12 sessions killed in a single second in one batch).
- The error message sends users to IT for a non-existent security product. Considerable time was lost chasing that before the app's own logs identified the real killer.
- Workaround that shouldn't be necessary: keeping raw free memory artificially high by quitting other applications.
Suggested fixes
- Gate on
kern.memorystatus_vm_pressure_level(orDISPATCH_SOURCE_TYPE_MEMORYPRESSURE) rather than raw free pages. Optionally also require non-trivial swap activity before acting. - Never attribute a self-inflicted SIGKILL to endpoint security. If the app's own watchdog reaped the process, say so — and ideally log the metric and threshold that fired. The current message is actively misleading on machines with no security software installed.
- If a memory guard is genuinely required, warn before reaping so in-flight work can be checkpointed.
Reproduction
Not deterministic, but reliably reproduced by running several concurrent Claude Code sessions plus ordinary developer processes (a dev server, a browser) on a 16 GB Mac until sys_free_raw drops below ~800 MB — visible in the app's own [process-memory] interval log lines. Kills follow within ~30 s while macOS reports normal pressure and zero swap.
Happy to supply full anonymised log extracts on request.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗