Skip to content

Config hot-reload spawns orphan gateway process when running under systemd #7421

@brunocfalcao

Description

@brunocfalcao

Description

When the gateway is running under systemd and a config change triggers a restart (via SIGUSR1 hot-reload), the gateway spawns a new process that is NOT managed by systemd. This creates an "orphan" process that blocks subsequent systemd restart attempts.

Detected during debugging session with Claude Code

Environment

  • OpenClaw version: 2026.2.1
  • OS: Ubuntu Linux (systemd user service)
  • Node: 22.x

Steps to Reproduce

  1. Run gateway via systemd: systemctl --user start openclaw-gateway
  2. Change a config value that requires restart (e.g., agents.defaults.model.primary)
  3. Gateway detects change, sends SIGUSR1 for hot-reload
  4. A NEW process spawns outside systemd's control
  5. Systemd tries to restart but fails because orphan holds port 18789
  6. Results in restart storm (29 failed attempts in my case)

Expected Behavior

When running under systemd (detected via OPENCLAW_SYSTEMD_UNIT env var), config changes requiring restart should either:

  1. Use systemctl --user restart openclaw-gateway instead of spawning directly
  2. Or do a true in-process restart without forking new PIDs

Actual Behavior

Gateway spawns new process via CLI invocation (with --force flag), creating orphan that blocks systemd-managed restarts.

Logs

17:55:16 [reload] config change requires gateway restart (meta.lastTouchedAt)
17:55:16 [gateway] signal SIGUSR1 received
17:55:42 [gateway] signal SIGTERM received
17:55:57 [gateway] listening on ws://127.0.0.1:18789 (PID 334259)  # NEW orphan PID!
17:56:08 [gateway] force: killed pid 334259 (openclaw-gatewa) on port 18789
17:56:08 [gateway] listening on ws://127.0.0.1:18789 (PID 334429)  # Another orphan!
17:56:16+ systemd: Failed with result 'exit-code' (29 times)

Workaround

Kill orphan processes and restart via systemd:

pkill -f openclaw-gateway && systemctl --user start openclaw-gateway

Suggested Fix

In the hot-reload code, detect if running under systemd:

if (process.env.OPENCLAW_SYSTEMD_UNIT) {
  // Use systemd to restart instead of spawning directly
  execSync('systemctl --user restart ' + process.env.OPENCLAW_SYSTEMD_UNIT);
} else {
  // Current behavior for non-systemd environments
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingstaleMarked as stale due to inactivity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions