I'm trying to pair two OpenClaw gateways as nodes to each other (bidirectional). Both are v2026.3.8. Gateway A (Windows) has gateway.bind: "lan" and gateway.auth.mode: "token".
Gateway B (EC2 Linux) connects to Gateway A via SSH reverse tunnel (ssh -R 18791:127.0.0.1:18789), then runs:
OPENCLAW_GATEWAY_TOKEN="<correct-token>" openclaw node run --host 127.0.0.1 --port 18791 --display-name "EC2-Gateway"
Result: node host gateway connect failed: Unexpected server response: 401
What works:
- Raw WebSocket from EC2 through the same tunnel with explicit
Authorization: Bearer <token> header → HTTP 200 (upgrade succeeds)
openclaw node run locally on the Windows gateway itself → gets past auth to "pairing required" (expected for new device)
What I've ruled out:
- Wrong token (verified matches
gateway.auth.token)
- IPv6 (
localhost vs 127.0.0.1 in tunnel target)
sudo env stripping (tested as both ubuntu and openclaw users, also with clean OPENCLAW_HOME)
- Stale
node.json (tested with fresh temp directory)
Theory: openclaw node run may not include the gateway token in the HTTP upgrade request headers — only at the WS protocol level. Local connections seem to be exempt from HTTP-level auth, but tunneled connections (which also arrive from 127.0.0.1) are not.
Questions:
- Does
openclaw node run pass the token in the HTTP Authorization header during WebSocket upgrade?
- Is there a config option to allow unauthenticated WS upgrades when protocol-level auth will follow?
- Any recommended approach for bidirectional node pairing between two gateways?
Related feature request: #42792 (--header support for Cloudflare Zero Trust service tokens)
I'm trying to pair two OpenClaw gateways as nodes to each other (bidirectional). Both are v2026.3.8. Gateway A (Windows) has
gateway.bind: "lan"andgateway.auth.mode: "token".Gateway B (EC2 Linux) connects to Gateway A via SSH reverse tunnel (
ssh -R 18791:127.0.0.1:18789), then runs:Result:
node host gateway connect failed: Unexpected server response: 401What works:
Authorization: Bearer <token>header → HTTP 200 (upgrade succeeds)openclaw node runlocally on the Windows gateway itself → gets past auth to "pairing required" (expected for new device)What I've ruled out:
gateway.auth.token)localhostvs127.0.0.1in tunnel target)sudoenv stripping (tested as bothubuntuandopenclawusers, also with cleanOPENCLAW_HOME)node.json(tested with fresh temp directory)Theory:
openclaw node runmay not include the gateway token in the HTTP upgrade request headers — only at the WS protocol level. Local connections seem to be exempt from HTTP-level auth, but tunneled connections (which also arrive from127.0.0.1) are not.Questions:
openclaw node runpass the token in the HTTPAuthorizationheader during WebSocket upgrade?Related feature request: #42792 (
--headersupport for Cloudflare Zero Trust service tokens)