#gateway connect failed: Error: unauthorized: device token mismatch (rotate/reissue device token)
1 messages · Page 1 of 1 (latest)
Your config snippet is almost right — it’s just in the wrong place.
Those settings live under gateway.*, not at the top level. So what you posted:
controlUi: { ... },
auth: { ... }
should be:
{
gateway: {
auth: {
mode: "token",
token: "<token>" // use normal quotes, not “smart quotes”
},
controlUi: {
allowInsecureAuth: true,
dangerouslyDisableDeviceAuth: true // break-glass only
}
}
}
After changing config, restart the gateway.
Why you still see “device token mismatch”
That error usually means the client (Control UI in the browser, or the CLI) has a stale cached device token from before the update.
Fix for the Control UI (browser)
- Clear site data for the dashboard origin (localStorage) and reload.
- Reconnect → you’ll likely get “pairing required”.
- On the gateway host, approve it:
openclaw devices list openclaw devices approve <requestId>
Fix for the CLI
The CLI caches its device token in:
~/.openclaw/identity/device-auth.json
Move it aside (safer than deleting), then try again:
mv ~/.openclaw/identity/device-auth.json ~/.openclaw/identity/device-auth.json.bak
Then re-run your openclaw ... command and approve the new pairing request (same openclaw devices ... flow as above).
Docs:
- Control UI + pairing: https://docs.openclaw.ai/web/control-ui
- Devices CLI: https://docs.openclaw.ai/cli/devices
If it still fails, paste (1) openclaw --version and (2) openclaw gateway status (and mention whether you’re connecting via localhost, LAN IP, or Tailscale).
running it via docker. If I run the docker-openclaw-cli i get the following:
docker compose run --rm openclaw-cli devices list
Container openclaw-openclaw-cli-run-47485d2a49f7 Creating
Container openclaw-openclaw-cli-run-47485d2a49f7 Created
🦞 OpenClaw 2026.2.17 (4134875) — Hot reload for config, cold sweat for deploys.
│
â—‡
[openclaw] CLI failed: Error: gateway closed (1006 abnormal closure (no close frame)): no close reason
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/node/.openclaw/openclaw.json
Bind: loopback
at Object.onClose (file:///app/dist/call-UGOrZHFc.js:266:10)
at WebSocket.<anonymous> (file:///app/dist/client-z7qQOWgJ.js:1512:23)
at WebSocket.emit (node:events:519:28)
at WebSocket.emitClose (/app/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket.js:263:12)
at emitErrorAndClose (/app/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket.js:1047:13)
at ClientRequest.<anonymous> (/app/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket.js:886:5)
at ClientRequest.emit (node:events:519:28)
at emitErrorEvent (node:_http_client:107:11)
at Socket.socketErrorListener (node:_http_client:574:5)
at Socket.emit (node:events:519:28)
That CLI error is a pure Docker networking issue: inside the openclaw-cli container, ws://127.0.0.1:18789 points back to the CLI container itself, not to your gateway container. So the WS connect fails (1006).
1) Point the CLI at the gateway container, not localhost
Find your gateway service name:
docker compose ps
If it’s openclaw-gateway (what the docs use), run:
docker compose run --rm openclaw-cli devices list \
--url ws://openclaw-gateway:18789 \
--token "$OPENCLAW_GATEWAY_TOKEN"
If your gateway service is named openclaw, use:
docker compose run --rm openclaw-cli devices list \
--url ws://openclaw:18789 \
--token "$OPENCLAW_GATEWAY_TOKEN"
(You can also hardcode the token instead of $OPENCLAW_GATEWAY_TOKEN if you’re not loading a .env into the compose services.)
2) Make sure the gateway is listening on the container interface
In Docker, the gateway should bind to LAN inside the container:
{
gateway: {
bind: "lan"
}
}
If it’s bound to loopback, other containers won’t be able to reach it even with the right --url.
3) After you can connect, then fix the “device token mismatch”
That mismatch is typically fixed by clearing the cached device token on the client:
- CLI cache file (in the state dir you mounted/persisted):
~/.openclaw/identity/device-auth.json - Control UI: clear site data / use a fresh browser profile, then approve the new device.
Docs (Docker section includes the exact devices approve flow):
https://docs.openclaw.ai/install/docker
If you paste the output of docker compose ps and the relevant part of your docker-compose.yml service names (gateway + cli), I can tell you the exact --url to use.
Solved
Glad it’s sorted.
If you can, please mark the solution in this thread (right‑click the message that fixed it → Apps → ✅ Mark Solution) so Answer Overflow indexes it for the next person.