OpenClaw "gateway closed (1006 abnormal closure (no close frame)): no close reason"
Last checked
The error
gateway closed (1006 abnormal closure (no close frame)): no close reason
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: ~/.openclaw/openclaw.json
Bind: loopbackPrinted by CLI commands such as openclaw health, cron list, or agents delete. Health checks print it prefixed with "Health check failed:". The gateway log shows lines like "[ws] webchat disconnected code=1006".
WebSocket code 1006 is not sent by anyone. It is what the client reports when the connection to the gateway vanished without a close frame: the gateway process died or restarted, it was too busy to answer, or something in between (nginx, Caddy, a load balancer, a VPN) cut the socket. Run openclaw gateway status first. If the gateway is up, check the proxy idle timeout and the gateway's event-loop load.
Why it happens
A clean shutdown sends a close frame with a code like 1000 or 1012. 1006 means the TCP connection ended with no frame at all, so the client only knows that the line went dead, not why.
- The gateway process crashed, was killed, or restarted mid-request (for example by launchd, systemd, or an update). Issue #7976 reported intermittent health-check failures with exactly this text on a macOS LaunchAgent gateway.
- The gateway was alive but starved. On 2026.9.6, users reported event-loop stalls with "[ws] webchat disconnected code=1006" in the log (issue #157545), and config hot reload can block the event loop for 20 to 33 seconds (issue #159698, open).
- A reverse proxy dropped an idle socket. nginx closes a proxied connection when nothing is read for proxy_read_timeout, which defaults to 60 seconds, and it does so without a WebSocket close frame.
- Wrong scheme: connecting with ws:// to a wss:// gateway, or the reverse. The CLI lists this as a possible cause next to the error.
- Some CLI commands closed the socket abnormally after a doctor repair on 2026.6.11 while openclaw gateway health still passed (issue #98753, open).
The fix
- 1 Check the process: openclaw gateway status. If it is not running or its PID just changed, read openclaw logs --follow for the crash or restart reason before anything else.
- 2 If the gateway is up, rerun the command. A one-off 1006 during a restart or reload is expected.
- 3 Behind nginx, keep the WebSocket upgrade headers and raise the read and send timeouts on the gateway location (see the block below), then reload nginx. For Caddy or a cloud load balancer, raise its idle timeout the same way.
- 4 Match the scheme to the gateway: wss:// when TLS terminates in front of it, ws:// for plain loopback.
- 5 If it happens under load, check the log for event-loop or heartbeat warnings near the disconnect, and upgrade past the release named in the matching issue.
- 6 Run openclaw doctor for anything config-shaped.
openclaw gateway statusnginx settings that stop idle 1006 drops
nginx's proxy_read_timeout and proxy_send_timeout both default to 60s. A gateway connection that goes quiet for longer is cut, and the client reports 1006. Keep the upgrade headers and set longer timeouts on the location that proxies the gateway:
location / {
proxy_pass http://127.0.0.1:18789;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}If the handshake itself fails you get a 400, not a 1006. That is the missing upgrade headers case, covered on the WebSocket 400 page.
Did my command run anyway?
Maybe. If the socket dropped after the CLI sent a write, the gateway may already have applied it. Before 2026.9.6 the CLI printed the same message and advised a retry either way (issue #154281). From 2026.9.6 it warns that the outcome is unknown (PR #154282). Check the current state, for example openclaw agents list or openclaw cron list, before repeating a write.
Still failing?
- If the gateway restarts on its own, look for a crash loop or memory pressure in openclaw logs --follow and in your service manager's logs.
- If only certain commands fail while openclaw gateway health passes, capture the exact command and version and compare with issue #98753.
- If it only happens through the proxy, test the same command directly against ws://127.0.0.1:18789 on the host to isolate the proxy.
Related errors
Hit a different error?
Paste any agent error and get the cause and fix in seconds.
Frequently asked questions
Is 1006 an OpenClaw bug?
Not by itself. 1006 is a client-side code meaning the connection ended without a close frame. The cause is whatever cut the connection: a crash, a restart, a busy event loop, or a proxy timeout.
Why do I get 1006 every minute or so behind nginx?
That pattern matches nginx's 60 second default proxy_read_timeout. Raise proxy_read_timeout and proxy_send_timeout on the gateway location and reload nginx.
Should I just retry?
For reads, yes. For writes such as deleting an agent or editing cron, check the current state first, because the gateway may have applied the change before the socket died.
Stop firefighting agent errors
Decoding errors one at a time is the manual version of what BetterClaw automates. Run your agents on a no-code AI agent platform with managed models, retries and config validation built in.
Free plan available · Pro $49/mo · BYOK · 7-day money-back guarantee
