Documentation Index
Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
Why
- Ensure only one gateway instance runs per base port on the same host; additional gateways must use isolated profiles and unique ports.
- Survive crashes/SIGKILL without leaving stale lock files.
- Fail fast with a clear error when the control port is already occupied.
Mechanism
- The gateway first acquires a per-config lock file under the state lock directory and probes the configured port for an existing listener.
- If the recorded lock owner is gone, the port is free, or the lock is stale, startup reclaims the lock and continues.
- The gateway then binds the HTTP/WebSocket listener (default
ws://127.0.0.1:18789) using an exclusive TCP listener. - If the bind fails with
EADDRINUSE, startup throwsGatewayLockError("another gateway instance is already listening on ws://127.0.0.1:<port>"). - On shutdown the gateway closes the HTTP/WebSocket server and removes the lock file.
Error surface
- If another process holds the port, startup throws
GatewayLockError("another gateway instance is already listening on ws://127.0.0.1:<port>"). - Other bind failures surface as
GatewayLockError("failed to bind gateway socket on ws://127.0.0.1:<port>: …").
Operational notes
- If the port is occupied by another process, the error is the same; free the port or choose another with
openclaw gateway --port <port>. - Under a service supervisor, a new gateway process that sees an existing healthy
/healthzresponder exits successfully and leaves that process in control. If the existing process never becomes healthy, retries are bounded and startup fails with a clear lock error instead of looping forever. - The macOS app still maintains its own lightweight PID guard before spawning the gateway; the runtime lock is enforced by the lock file plus HTTP/WebSocket bind.
Related
- Multiple Gateways — running multiple instances with unique ports
- Troubleshooting — diagnosing
EADDRINUSEand port conflicts