[Bug]: OpenClaw leaks unreaped hook/tool child processes, causing zombie accumulation and runtime degradation
Bug type
Regression (worked before, now fails)
Beta release blocker
No
Summary
Summary
OpenClaw appears to leak unreaped child processes from hook/tool execution. Over time these accumulate as zombies under the main openclaw process (openclaw-hooks, bash, codex, and occasionally chrome-headless). Once enough accumulate, the runtime degrades and can eventually fail to spawn new helper work (spawn EAGAIN, uv_thread_create, gateway instability, connector silence). Restarting OpenClaw immediately clears the process table and restores service until the leak accumulates again.
This is not a single connector failure in our deployment: we have seen the same shape across multiple OpenClaw 2026.6.x versions, and the current affected runtime reports:
OpenClaw 2026.6.10 (aa69b12)
Environment
- Runtime: OpenClaw
2026.6.10 (aa69b12) - OS: Debian 12 GCE VM
- OpenClaw launched in Docker with host networking
- Workload:
- Slack provider enabled
- Telegram provider enabled
- Codex provider enabled
- scheduled/cron work enabled
- hook/tool plugins enabled
- The issue is most visible on a busy runtime, but the leak pattern is not limited to a single connector. We also see stale
bashandcodexchildren, not only connector-specific workers.
Symptoms
After OpenClaw has been running for hours, process pressure grows steadily. A recent sanitized snapshot:
total processes: 336
zombies: 225
dstate: 1
zombie_comm openclaw-hooks 113
zombie_comm bash 108
zombie_comm codex 2
zombie_comm chrome-headless 2
The zombie children are parented by the main openclaw process:
PID PPID STAT ELAPSED COMMAND
141806 141784 Ssl 20:12:59 openclaw
142413 141806 ZNs 20:07:50 [openclaw-hooks] <defunct>
143325 141806 ZNs 20:00:41 [openclaw-hooks] <defunct>
177641 141806 Z 11:33:55 [codex] <defunct>
...
OpenClaw health remains nominal for a while, but the process table continues growing:
{
"openclaw_reachable": true,
"telegram": { "ready": true },
"slack": { "ready": true },
"process_pressure": {
"degraded": false,
"restart_recommended": false,
"process_count": 326,
"zombies": 225,
"hook_zombies": 113,
"d_state": 0,
"reasons": []
}
}
When the leak gets worse, the same runtime reaches degraded/restart territory:
{
"process_count": 1003,
"zombie_processes": 889,
"hook_zombie_processes": 798,
"d_state_processes": 1,
"reasons": [
"hook_zombie_warning",
"hook_zombie_degraded"
],
"thresholds": {
"hook_zombie_warning": 250,
"hook_zombie_degraded": 750,
"hook_zombie_restart": 800,
"total_zombie_restart": 1000
}
}
In worse incidents we observed downstream runtime failures such as:
spawn EAGAINuv_thread_create- gateway health timeouts / intermittent gateway unavailability
- Slack/Telegram messages not being processed
- task failures where OpenClaw can no longer start expected helper work
Restarting OpenClaw clears the zombies immediately and restores the runtime, which strongly suggests unreaped children rather than external API/network failure.
Secondary effect: monitoring traffic ramps up
On GCE with Google Ops Agent installed, outbound network slowly increases until OpenClaw is restarted. Packet sampling showed the largest outbound flow was the Ops Agent (otelopscol) exporting host/process metrics, not OpenAI/Slack/Telegram payloads.
This appears to be a consequence of the leak: as the process table grows, per-process metrics export grows. After OpenClaw restart, process count drops and the outbound metric volume falls.
Expected behavior
OpenClaw should reap hook/tool child processes when they exit, including subprocesses created by hook runners and embedded provider/tool helpers. Completed hook/tool invocations should not leave zombie openclaw-hooks, bash, codex, or browser-helper children indefinitely.
Actual behavior
Defunct children remain parented to openclaw for many hours, accumulating until runtime health degrades. Restarting OpenClaw is currently the only reliable recovery.
Why this looks like an OpenClaw process lifecycle bug
- Zombies are direct children of the main
openclawprocess. - They survive after the tool/hook work has completed.
- They include generic hook/tool child processes (
openclaw-hooks,bash,codex,chrome-headless), not just one connector-specific worker. - The problem clears only when the parent OpenClaw process is restarted.
- We have reproduced the pattern across multiple 2026.6.x versions.
Related / possibly adjacent issues
These may be related but do not seem to cover the same root issue:
- #79224
- #77249
- #88870
Useful diagnostics we can provide
We can provide more sanitized snapshots if useful:
ps -eo pid,ppid,stat,etime,comm,args- OpenClaw gateway logs around the degradation window
- process-pressure watcher summaries
- packet-header-only traffic samples showing Ops Agent traffic growing with process count
Steps to reproduce
I do not yet have a minimal synthetic reproducer, but the issue is reproducible in a long-running OpenClaw runtime under connector/tool load:
- Run OpenClaw 2026.6.x on a Linux VM with gateway enabled.
- Configure Slack and/or Telegram connectors.
- Enable hook/tool execution paths that spawn child processes, including connector ingestion, scheduled/cron tasks, and normal agent tool calls.
- Let the runtime process real connector traffic for several hours without restarting the OpenClaw container.
- Periodically inspect the OpenClaw process tree with
ps,pstree, or equivalent host process metrics.
Observed result: child processes created by OpenClaw/tool/hook execution become zombies and remain parented under the OpenClaw process instead of being reaped. The zombie count grows over time, eventually causing process/thread exhaustion and runtime degradation.
Expected behavior
OpenClaw should reap all completed hook/tool child processes promptly.
A long-running gateway/runtime should keep a stable process count under normal connector and tool usage. Completed child processes should not accumulate as zombies, and the runtime should not degrade into spawn EAGAIN, uv_thread_create, gateway timeouts, connector silence, or required container restarts.
If a tool or hook subprocess cannot be reaped normally, OpenClaw should detect it, log a bounded diagnostic, clean it up or quarantine it, and continue operating without unbounded zombie/process growth.
Actual behavior
Completed hook/tool child processes remain as zombies parented under the OpenClaw runtime process.
Over time the zombie count and total process count grow without being cleaned up. Once enough zombies accumulate, the runtime begins failing unrelated operations because the host/container hits process or thread limits.
Observed failures include:
spawn EAGAINuv_thread_createfailures from Node- gateway requests timing out or becoming intermittently unavailable
- Slack/Telegram connectors appearing configured but no longer responding reliably
- normal shell commands such as
psorulimitfailing withResource temporarily unavailable - runtime recovery requiring an OpenClaw/container restart, after which the zombie count drops and service resumes
This appears to be cumulative: the runtime can work normally for hours, then progressively degrades as unreaped child processes build up.
OpenClaw version
2026.06.10
Operating system
Debian 12 on Google Compute Engine VM
Install method
Docker image deployed by provisioning automation/Terraform on a GCE VM. OpenClaw runs as a long-lived container with host networking, managed by systemd.
Model
GPT-5.5 on Codex subscription
Provider / routing chain
User message arrives through Slack or Telegram connector, then through the local OpenClaw gateway/runtime on the VM, then to the configured OpenAI/Codex provider path used by the OpenClaw agent. The issue appears before or around local hook/tool/process execution and is not specific to one upstream model response path.
Additional provider/model setup details
The affected runtime uses OpenClaw gateway mode with connector channels enabled for Slack and Telegram. The agent is configured with OpenAI/Codex auth for main turns, plus local tools/hooks and scheduled jobs.
The zombie accumulation appears tied to local subprocess lifecycle management for hooks/tools/connectors, not to API key validity or model selection. We have observed it across multiple OpenClaw 2026.6.x versions and after changing VM size. Restarting the OpenClaw container clears the accumulated zombies temporarily, but they start accumulating again during normal connector/tool activity.
No API keys, tokens, or secrets are included here.
Logs
# One example:
OpenClaw process pressure:
source host_proc
hook zombies: 800+
total zombies: 800+
total processes: 900+
D-state processes: 1
restart recommended
# Another one:
OpenClaw process pressure:
hook zombies: ~4000
total zombies: ~4000
process/thread exhaustion symptoms present
Screenshots, recordings, and evidence
Impact and severity
Affects users - needed to create a separate watcher that restarts OpenClaw every few hours
Additional information
Did not notice this issue before 2026.6.8 (maybe should say before 2026.6.X)
Source: openclaw/openclaw