[**SEVERE ISSUE**][Windows App 26.707.12708.0] single Node MCP child reaches 112 GB and exhausts system commit
What version of the Codex App are you using?
OpenAI.Codex_26.707.12708.0_x64
The machine has since updated to 26.715.2236.0, but that build has not yet been exercised long enough to establish whether the defect is fixed.
Platform
- Windows 11 Pro, x64
- Approximately 64 GB RAM
- Codex Desktop / bundled app-server
Severity
Severe. A single Codex-owned Node MCP child consumed approximately 112 GB of committed virtual memory, exhausted the Windows system commit limit, crashed the Codex app-server, and continued growing after the app-server exited.
This is distinct from reports where many normal-sized MCP processes accumulate. The existing per-thread MCP fleet retention appears to be a trigger/amplifier, but one individual node.exe process entered a catastrophic allocation loop.
What happened?
Windows Resource-Exhaustion-Detector Event ID 2004 recorded the following sequence during the final incident:
| UTC time | Process | Committed virtual memory |
|---|---|---:|
| 2026-07-16T22:46:11Z | node.exe PID 5868 | 96,918,151,168 bytes |
| 2026-07-16T22:46:11Z | Codex app-server PID 1072 | 1,894,060,032 bytes |
| 2026-07-16T22:47:19Z | the same node.exe PID 5868 | 111,670,394,880 bytes |
<img width="465" height="299" alt="Image" src="https://github.com/user-attachments/assets/60ed6dd6-6d82-45df-99bc-1560e9fa6a0a" />
<img width="698" height="458" alt="Image" src="https://github.com/user-attachments/assets/73e7d896-0ca9-4ea8-931f-d7ceb5346a0e" />
At the first warning, Windows reported:
SystemCommitLimit = 130,234,757,120
SystemCommitCharge = 130,214,023,168
Thirteen seconds after the first warning, Codex Desktop logged:
app_server_connection.closed code=3221226505
reason="memory allocation of 2097152 bytes failed"
3221226505 is 0xC0000409.
The app-server failed to obtain an ordinary 2 MB allocation because the Node child had consumed almost all system commit. The same Node PID was then recorded at 111.7 GB about 55 seconds after the app-server exited, indicating that the child survived its owning app-server and continued allocating.
At least one earlier incident on the same installation showed a different node.exe PID consuming 96,191,614,976 bytes. Additional Event ID 2004 records show the same failure class with other short-lived Node PIDs reaching roughly 68-110 GB. This is therefore recurrent rather than a one-time damaged process.
MCP and subagent correlation
Structured Codex telemetry for the final seven-minute incident window showed:
- 14 distinct active thread IDs
- 5,230
codex_mcp::connection_managerevents - 14 MCP server names repeatedly initialized/enumerated
- a
spawn_agentpath enteringsession_init.mcp_manager_init - eight local MCP children exiting between
22:45:01Zand22:45:05Z - another local MCP fleet being resolved/launched at
22:45:18Z-22:45:19Z
The synchronized child exits included several different MCP servers and appear to represent fleet teardown/recreation, not proof that any one named server was responsible.
The same broad pattern was present around four separate memory-exhaustion windows: multiple active threads, repeated complete MCP tool enumeration, and one Node process becoming the dominant system commit consumer.
Attribution limit
The exact MCP package owning the runaway PID cannot be identified from the retained diagnostics:
- Codex telemetry records
server_namefor MCP initialization but not the spawned child OS PID. - The Desktop
electron-samplerparent-process snapshot failed before preserving the process tree and command lines. - Windows process-creation auditing and Sysmon were not enabled at the time.
- Event ID 2004 identifies the executable and PID, but not its command line or parent.
Several configured MCP servers are Node-backed. No individual server should be blamed without a PID-to-server mapping.
A current healthy baseline shows these Node MCP processes using roughly 34-166 MB of private committed memory each, which confirms that 96-112 GB is an abnormal runaway rather than their normal footprint.
Steps to reproduce
The exact trigger is intermittent, but all confirmed incidents occurred under this workload shape:
- Configure multiple global and plugin-provided stdio MCP servers.
- Start Codex Desktop on Windows.
- Keep several tasks/threads active.
- Spawn multiple subagents so each runtime initializes the configured MCP fleet.
- Continue normal work for several minutes.
- Observe Codex-owned Node children and Windows commit usage.
- One Node child may rapidly become the dominant commit consumer, followed by Event ID 2004 and app-server
0xC0000409allocation failure.
Expected behavior
- MCP child count and aggregate memory remain bounded across threads and subagents.
- Completed, failed, or superseded runtimes close their stdio transports and terminate their complete Windows process trees.
- A single MCP child cannot consume enough commit to destabilize the host; Codex applies memory backpressure or terminates/restarts the child.
- Diagnostics record the owning task/thread, MCP
server_name, child PID, creation time, and termination reason.
Suggested engineering checks
- Add
server_nameto spawned-child PID lifecycle telemetry. - Place each runtime-owned MCP tree in a Windows Job Object and terminate the tree when its owner exits.
- Pool identical MCP servers across threads, or start them lazily instead of eagerly launching a complete fleet per subagent.
- Add per-child and aggregate MCP memory limits with backpressure before Windows commit is exhausted.
- Audit cancellation/retry paths around
spawn_agentandsession_init.mcp_manager_initfor fleet recreation without complete teardown. - Ensure app-server exit also terminates descendants rather than allowing a runaway child to survive and continue allocating.
Related issues
- #33531: Windows MCP suites persist after subagents complete
- #30408: per-thread MCP processes are not reliably cleaned up
- #32797: repeated retained MCP/Node process batches on Windows
- #29317: separate severe Windows commit-exhaustion case involving a PowerShell helper rather than a Node MCP child
This report is intentionally separate because the decisive failure is one node.exe process consuming 112 GB, not merely the aggregate cost of many retained MCP processes.
No task contents, client or project names, usernames, absolute paths, credentials, raw command lines, or private thread IDs are included.
6 Comments
Follow-up after Desktop update
The machine has now updated to Codex Desktop
26.715.2305.0, running app-server0.145.0-alpha.18.The catastrophic 96–112 GB single-Node runaway has not yet reproduced on this build. However, the underlying MCP lifecycle behavior remains present.
During one controlled recovery session, one app-server created six MCP runtime batches within approximately one minute. After roughly eight minutes, its process tree contained:
node.exechildrenIndividual Node processes remained healthy at approximately 34–166 MB. This confirms that
26.715.2305.0still multiplies and retains MCP process suites, although the reduced MCP configuration kept aggregate memory bounded during this observation.The severe single-process allocation loop remains intermittent and unconfirmed on the updated build. The lifecycle/retention portion is not resolved.
Cross-harness reproduction and effective containment
A related host-risk pattern was subsequently reproduced in OpenCode while running
gpt-5.6-solat extra-high reasoning. This is useful because it shows the failure is not limited to the Codex Desktop UI, but the captured OpenCode child was a shell-launched Node test runner rather than an identified MCP server:While that child was active, physical memory climbed rapidly toward exhaustion. Stopping the agent stream ended the child process and memory returned to normal. Investigation found that the focused RED test was repeatedly waiting for an impossible UI state. After correcting that product/test behavior, the same test completed normally.
Important scope note: this does not prove that
gpt-5.6-solitself owns the allocation or that every reasoning level reproduces it. It shows that agent harnesses need a resource boundary around all locally spawned Node children, including MCP servers, test runners, package-manager commands, and other shell subprocesses. A model can amplify the workload, but the local harness must prevent one child from exhausting host commit.Containment applied in OpenCode
A global OpenCode plugin now injects the following into every agent shell execution and every local MCP server environment:
Focused regression tests are run with a stricter temporary ceiling:
After the application/test correction and the temporary 1 GB test ceiling:
Limitation of this workaround
--max-old-space-sizelimits V8 old-space only. It does not cap native allocations, external buffers, memory mappings, aggregate memory across many children, or non-Node subprocesses. A process may also terminate with OOM when it reaches the ceiling.Recommended harness-level fix
On Windows, each agent-owned subprocess tree should be placed inside a Job Object with both per-process and aggregate committed-memory limits. The harness should also:
The OpenCode workaround demonstrates an immediately effective V8-level mitigation, but OS-level process-tree containment is required for a complete fix.
OpenCode-specific follow-up
The fallback workflow later reproduced a related resource-containment failure in OpenCode Desktop 1.18.3 while using
openai/gpt-5.6-sol. The captured consumer there was a shell-launched Node test runner, not an identified MCP server, so it is now tracked separately at anomalyco/opencode#37597.The affected OpenCode sessions moved between
xhigh,high, andmedium. This does not establish model causation; it establishes that both harnesses can allow an agent-owned Node subprocess tree to threaten host memory without an OS-level boundary.Local containment has since been narrowed to recognized Node test commands only: each runs in a Windows Job Object capped at 1.5 GB per process and 3 GB per command tree. Normal desktop/chat processes are not capped. A synthetic external-buffer allocation hit the boundary in under one second and left no surviving child.
The original Codex attribution remains unchanged: the 96–112 GB Codex-owned Node PID could not be mapped to a specific MCP package from retained telemetry.
Observation after the 2026-07-18 Desktop update
The machine is now running Codex Desktop
26.715.3651.0. The package was installed at approximately2026-07-18T05:18Z, and the observed app-server started at approximately05:24Z.A read-only three-minute sample after startup remained flat:
node.exedescendants throughout1,104.0–1,105.1 MB104.7–104.8 MB1,679.0–1,696.9 MBThis is materially healthier than the earlier observation on
26.715.2305.0, where one app-server created six MCP runtime batches and reached 24 Node descendants / 2.63 GB tree private memory within roughly eight minutes.However, I cannot mark the defect fixed yet:
Current status: not reproduced on
26.715.3651.0during a short stable observation, but not yet confirmed resolved.Correction: recurrence after the short
26.715.3651.0sampleThe prior three-minute observation was a false negative, not evidence of resolution.
At
2026-07-18T05:45:58Z, approximately eight minutes after that flat sample ended, Windows Resource-Exhaustion-Detector Event ID 2004 recorded:This confirms that the severe failure class recurred while Desktop
26.715.3651.0was installed. Retained Windows telemetry does not preserve the dead PID's command line or parent, so this event alone cannot be attributed to Codex versus another simultaneously running agent harness.Two later Node runaways at
08:22:19Zand08:24:34Zreached 82.69 GB and 93.19 GB. Those later events correlate strongly with a Cursor agent launching repeated pnpm installs and then a combinedtypecheck; test; lint; buildcommand. The Codex AppX update to26.715.4045.0began at08:24:15Zand completed at08:25:59Z, after the first Cursor-correlated event had already occurred.Updated status:
26.715.3651.0: failure recurred; not resolved.26.715.4045.0: installed after the incident window; not yet validated.Attribution correction after Cursor session self-review
The Cursor correlation in my previous comment should be treated as possible, not strong attribution.
Cursor's retained conversation/tool history adds these facts:
ERR_PNPM_UNEXPECTED_STORE.typecheck; test; lint; buildcommand was requested in pre-tool hooks at08:24:18Z, but Cursor's retained execution history only proves a Vitest start at08:36:40Z, after the incident/restart window.Therefore:
08:22:19Z82.69 GB Node event occurred before the Codex AppX update and after Cursor's reported install calls had returned.08:24:34Z93.19 GB event overlaps both the start of the Codex update and a Cursor pre-tool request, but neither retained log proves ownership of that dead PID.Updated conclusion: ownership of the later PIDs remains unknown. The events still prove the cross-harness need for OS-level Node subprocess containment and PID-to-owner telemetry, but they do not justify assigning these two PIDs to Cursor or Codex.