Fix: "Pairing Required" Errors When Running OpenClaw in Docker
If you're running OpenClaw in Docker and getting "pairing required" or "disconnected (1008): pairing required" errors when trying to use the Control UI or internal tools like cron, you've hit a common Docker networking gotcha. Here's why it happens and three ways to fix it.
Why This Happens
OpenClaw's device pairing system auto-approves connections from 127.0.0.1 (loopback) but requires explicit approval for other IPs. The twist: the IP is determined from the Gateway's network namespace, not yours.
In Docker:
- You open
http://127.0.0.1:18789/on your host - The Gateway inside the container sees the connection from Docker's bridge IP (e.g.,
172.18.0.2) - That's non-local โ pairing required
Same issue affects cron jobs or CLI tools running in sidecars โ they connect via the bridge network, not true loopback.
Solution A: Approve Once and Persist (Recommended)
The simplest fix: just approve the device and make sure state persists.
# From within the container or via docker exec
openclaw devices list
openclaw devices approve <requestId>
# Or with docker-compose
docker compose run --rm openclaw-cli devices list
docker compose run --rm openclaw-cli devices approve <requestId>Critical: Make sure ~/.openclaw is bind-mounted or in a persistent volume. If you wipe state, you'll re-trigger pairing.
Solution B: Share the Network Namespace
If you have sidecar containers (cron runners, CLI tools) that need auto-approval, put them in the same network namespace as the gateway:
services:
openclaw-gateway:
# ... your gateway config
openclaw-cli:
network_mode: "service:openclaw-gateway"
# Now 127.0.0.1 is truly loopback from Gateway's POVThis makes ws://127.0.0.1:18789 genuinely local โ auto-approval works.
Alternative: network_mode: host on Linux (but changes your exposure model).
Solution C: Disable Device Pairing (Security Tradeoff)
If you trust your network and want to skip device pairing entirely for the Control UI:
{
"gateway": {
"controlUi": {
"allowInsecureAuth": true
},
"bind": "lan",
"auth": {
"mode": "token",
"token": "your-secret-token"
}
}
}This enables token-only auth without device identity verification. Only use this on trusted networks.
Quick Checklist
- Control UI in browser? โ Solution A (approve once) or C (if you want passwordless)
- Cron/CLI in sidecars? โ Solution B (share network namespace) or A (approve the sidecar's identity)
- Everything local but still failing? โ Check that state is persisting and browser isn't clearing storage
References
Props to GeekDad on Discord for raising this question and Krill for the detailed breakdown.
Comments (0)
No comments yet. Be the first to comment!