OpenClaw WebSocket 400 behind nginx / Caddy
A WebSocket 400 behind a reverse proxy means nginx or Caddy isn't forwarding the Upgrade headers, so the gateway's WebSocket connections silently drop. In nginx, set proxy_http_version 1.1 and forward the Upgrade and Connection: upgrade headers for the gateway location, then reload. Caddy's reverse_proxy passes upgrades by default unless you stripped the headers.
Likely cause
nginx or Caddy isn't forwarding the WebSocket Upgrade headers, so the gateway's WebSocket connections silently drop and log a 400.
The fix
- 1 In nginx, forward the upgrade headers for the gateway location: proxy_http_version 1.1, Upgrade, Connection upgrade, and Host.
- 2 Reload nginx.
- 3 For Caddy, ensure reverse_proxy passes WebSocket upgrades - it does by default unless you stripped headers.
proxy_set_header Upgrade $http_upgrade;Hit a different error?
Paste any agent error and get the cause and fix in seconds.
Frequently asked questions
The dashboard loads but live updates never arrive. Is that this bug?
Often, yes. If the WebSocket handshake returns 400 the page loads over HTTP but real-time updates never connect. Forwarding the Upgrade headers in your proxy restores the live connection.
Which nginx directives do I actually need?
proxy_http_version 1.1, proxy_set_header Upgrade $http_upgrade, proxy_set_header Connection "upgrade", and proxy_set_header Host $host on the gateway location. Then reload nginx.
I'm on Caddy and it still drops. Why?
Caddy's reverse_proxy forwards WebSocket upgrades by default, so a drop usually means a custom header block stripped them. Remove the stripping, or explicitly pass the Upgrade and Connection headers.
Stop firefighting agent errors
Decoding errors one at a time is the manual version of what BetterClaw automates. Run your OpenClaw agents hosted with managed models, retries and config validation built in.
$19/month per agent · BYOK · 7-day money-back guarantee
