Health Checks and Gateway Monitoring for OpenClaw

Learn how to verify channel connectivity and monitor gateway health using OpenClaw commands. This page covers quick status checks, live probes, and diagnostic output for troubleshooting.

Read this when

  • Diagnosing channel connectivity or gateway health
  • Understanding health check CLI commands and options

Here is the rewritten documentation:

A concise way to confirm channel connectivity without relying on guesswork.

Quick checks

  • openclaw status - local overview: gateway reachability and mode, update notification, linked channel authentication age, sessions and recent activity.
  • openclaw status --all - comprehensive local diagnostic output (read-only, colorized, safe to share for troubleshooting).
  • openclaw status --deep - requests a live probe from the running gateway (health with probe:true), including per-account channel probes where supported.
  • openclaw status --usage - display model provider usage and quota snapshots.
  • openclaw health - fetches the running gateway's health snapshot (WebSocket-only; direct channel sockets are not available from the CLI).
  • openclaw health --verbose (also known as --debug) - triggers a live health probe and outputs gateway connection details.
  • openclaw health --json - machine-readable health snapshot output.
  • Send /status as a standalone chat command in any channel to receive a status reply without invoking the agent.
  • Logs: execute openclaw logs --follow (or openclaw --profile <profile> logs --follow) and filter for web-heartbeat, web-reconnect, web-auto-reply, web-inbound.

For Discord and other chat providers, session rows do not indicate socket liveness. openclaw sessions, Gateway sessions.list, and the agent sessions_list tool read stored conversation state. A provider can reconnect and show healthy channel status before any new session row is materialized. Use the channel status and health commands above for live connectivity checks.

Deep diagnostics

  • Creds on disk: ls -l ~/.openclaw/credentials/whatsapp/<accountId>/creds.json (mtime should be recent).
  • Session store: ls -l ~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite. Count and recent recipients are surfaced via status.
  • Relink flow: openclaw channels logout && openclaw channels login --verbose when status codes 409-515 or loggedOut appear in logs. The QR login flow auto-restarts once for status 515 after pairing.
  • Diagnostics are enabled by default (diagnostics.enabled: false disables them). Memory events record RSS/heap byte counts and threshold/growth pressure. Liveness warnings record event-loop delay/utilization, CPU-core ratio, and active/waiting/queued session counts when the process is running but saturated. Oversized-payload events record what was rejected/truncated/chunked plus sizes and limits, never message text, attachment contents, webhook bodies, raw request/response bodies, tokens, cookies, or secret values.
  • The same heartbeat drives the bounded stability recorder: openclaw gateway stability (or the diagnostics.stability Gateway RPC). Fatal Gateway exits, shutdown timeouts, and restart startup failures persist the latest snapshot under ~/.openclaw/logs/stability/. Inspect the newest bundle with openclaw gateway stability --bundle latest.
  • For bug reports, run openclaw gateway diagnostics export and attach the generated zip: a Markdown summary, the newest stability bundle, sanitized log metadata, sanitized Gateway status/health snapshots, and config shape. Chat text, webhook bodies, tool outputs, credentials, cookies, account/message identifiers, and secret values are omitted or redacted. See Diagnostics Export.

Health monitor config

  • channels.<provider>.healthMonitor.enabled: disable health-monitor restarts for a specific channel while leaving global monitoring enabled.
  • channels.<provider>.accounts.<accountId>.healthMonitor.enabled: multi-account override that wins over the channel-level setting.
  • These per-channel overrides apply to the channels that expose them today: Discord, Google Chat, iMessage, IRC, Microsoft Teams, Signal, Slack, Telegram, and WhatsApp.
  • A crashing channel is recovered by its own auto-restart backoff first (auto-restart attempt N/10 in the logs). The health monitor stays out of the way until that ladder ends with giving up after 10 restart attempts, then takes over as the last restart owner.

Inbound ingress health

Channel connectivity and inbound admission are separate failure domains. A channel can hold a healthy transport connection, sending replies normally, while its durable ingress queue is unavailable, so not a single inbound message is admitted.

  • When a channel cannot open its durable ingress queue, its start fails and the gateway records the account as unable to receive. openclaw channels status reports Channel cannot admit inbound events; its durable ingress queue is unavailable. Outbound may still work.
  • Such an account is unhealthy regardless of transport state, and readiness reports it as failing. Previously it reported health: healthy and the health monitor never touched it.
  • Recovery stays automatic. The ingress verdict describes the account's last start attempt and is cleared by the next one, so the ordinary restart path is also how a transient queue-open failure recovers. Those restarts log as health-monitor: restarting (reason: ingress-unavailable) instead of the generic stuck.
  • If the restarts keep repeating, the cause is not transient. Check the logged ingress failure: a plugin denied the openChannelIngressQueue capability, for example, needs operator action rather than another restart.
  • Channels that never report ingress state are unaffected: absence means "no signal", never "broken". There is no traffic-staleness heuristic, so a genuinely quiet channel is never marked unhealthy for having received nothing.

HTTP probes

The Gateway exposes three unauthenticated GET/HEAD probe pairs:

EndpointsMeaningUse
/health, /healthzThe HTTP server is live.Process liveness and restart decisions.
/startup, /startupzStartup work is complete and the Gateway is not draining. Channel health is not consulted.Orchestrator startup and traffic admission.
/ready, /readyzStartup is complete, the Gateway is not draining, and configured channel accounts pass deep readiness checks.Operator monitoring that should surface hard channel failures.

/startupz yields 503 together with status: "starting" while startup sidecars remain unfinished, 503 paired with status: "draining" during drain operations, and 200 alongside status: "started" in all other situations. Rely on it for traffic admission on Kubernetes, Fly, Render, and comparable platforms. A malfunctioning Telegram or other channel account can cause /readyz to respond with 503 even though a healthy Control UI stays online via /startupz.

Startup responses sent to unauthenticated remote callers carry only ok and status. Callers reaching the gateway locally or through authentication additionally get version, uptimeMs, and pendingReason while startup is in progress. Readiness details apply the same local-or-authenticated restriction, given that they may reference failing components.

Uptime monitoring

For external uptime monitoring, point to the dedicated /health endpoint rather than /v1/chat/completions.

  • Recommended: GET /health delivers an immediate reply, opens no session, triggers no LLM call, and returns {"ok":true,"status":"live"}
  • Avoid: /v1/chat/completions for health polling, since every request spins up a full agent session with skill snapshot, context assembly, and LLM invocations

When neither an x-openclaw-session-key header nor an user field is supplied, /v1/chat/completions assigns a fresh random session per request. A monitor hitting every 15 minutes produces roughly 96 sessions daily, each consuming 4-22KB. Left unchecked, this inflates the session store and risks context window overflow.

Monitoring service setup examples

  • BetterStack: Configure the health check URL as https://<your-gateway-host>:<port>/health
  • UptimeRobot: Create an HTTP monitor targeting https://<your-gateway-host>:<port>/health
  • Generic: Any HTTP GET against /health returns 200 with {"ok":true} whenever the gateway is operational

When something fails

  • logged out or status codes 409-515 -> re-establish the link using openclaw channels logout followed by openclaw channels login.
  • Gateway unreachable -> launch it via openclaw gateway --port 18789 (fall back to --force when the port is taken).
  • No inbound messages -> verify the linked phone is online and the sender is permitted (channels.whatsapp.allowFrom); for group chats, check that allowlist and mention rules align (channels.whatsapp.groups, agents.entries.*.groupChat.mentionPatterns).

Dedicated "health" command

openclaw health queries the running gateway for its health snapshot, avoiding direct channel sockets from the CLI. Its default behavior returns a fresh cached snapshot while the gateway refreshes that cache in the background; passing --verbose triggers a live probe instead. The command reports linked credential and auth age when available, per-channel probe summaries, session-store summary, and probe duration. A non-zero exit code indicates the gateway is unreachable or the probe failed or timed out.

Queue warnings

A successful health RPC reports the top-level ok: true. That value confirms the Gateway generated the snapshot, but does not guarantee every delivery queue is empty. Inspect deliveryQueues.ingressPressure for durable inbound lanes that might be holding up subsequent events. This field is omitted when no pressured lanes exist.

Ingress pressure relies on conservative built-in diagnostic thresholds, not on authoritative retry or claim policy for any plugin. A durable lane shows up only when an active pending or claimed row has either hit at least eight attempts with a recorded delivery error, or a claimed row has gone 30 minutes without refreshing its claim. Ordinary retries 1-7 stay hidden. Claim-recovery increments lacking a recorded error are also hidden, and live claims remain hidden because their claim timestamp stays refreshed. Rows without a durable lane key are excluded since they cannot demonstrate that later events are blocked; runtime persists a derived lane after a real derived-lane retry.

Results are grouped by channel account and include pressured lane, pending, claimed, and blocked counts along with the oldest affected receive time. All active rows within a pressured lane factor into those counts. The snapshot never exposes lane IDs, event IDs, payloads, claim owners or tokens, recorded errors, or session and target identifiers.

Options:

  • --json: output in machine-readable JSON
  • --timeout <ms>: change the default 10s probe timeout
  • --verbose: run a live probe and print gateway connection details
  • --debug: shorthand for --verbose

The health snapshot contains ok (boolean), ts (timestamp), durationMs (probe time), per-channel status, agent availability, session-store summary, and optional delivery-queue warnings.

1,535 words · updated Aug 16, 2026