How To Fix OpenClaw "Device Token Mismatch" Error (Quick Fix)

 · 3 min read  ·

If you’re running OpenClaw and suddenly start seeing this:

gateway closed (1008): unauthorized: device token mismatch (rotate/reissue device token)

Don’t panic. I spent way too long on this today. Here’s the fix so you don’t have to.

The Symptom

After updating to v2026.2.15, openclaw gateway status started showing:

RPC probe: failed
gateway closed (1008): unauthorized: device token mismatch (rotate/reissue device token)

openclaw doctor — didn’t detect it

openclaw gateway restart — same error

Deleting device identity files and re-pairing — still broken

Multiple reboots — nope

The Cause

OpenClaw stores a gateway auth token in two places:

  1. ~/.openclaw/openclaw.json — under gateway.auth.token
  2. The service file that keeps the gateway running in the background — as the OPENCLAW_GATEWAY_TOKEN environment variable

The service file location depends on your OS:

OSService file
Linux (systemd)~/.config/systemd/user/openclaw-gateway.service
macOS (launchd)~/Library/LaunchAgents/ai.openclaw.gateway.plist (or legacy com.openclaw.gateway.plist)

At some point (likely during an update or config change), these two values got out of sync. The CLI reads one token, the gateway process uses the other, and they reject each other.

The Fix (Linux)

I’m sure an actual fix is coming. For now, you need to make sure that these two auth tokens match.

Check it out with (or just ask OpenClaw to reconcile them):

# Get the token from openclaw.json
python3 -c "import json; c=json.load(open('$HOME/.openclaw/openclaw.json')); print(c['gateway']['auth']['token'])"

# Get the token from the systemd service
grep OPENCLAW_GATEWAY_TOKEN ~/.config/systemd/user/openclaw-gateway.service

If they’re different, that’s your problem. Copy the token from openclaw.json into the systemd service file:

# Edit the service file
nano ~/.config/systemd/user/openclaw-gateway.service

# Find the line:
# Environment=OPENCLAW_GATEWAY_TOKEN=<old_token>
# Replace <old_token> with the token from openclaw.json

# Reload and restart
systemctl --user daemon-reload
systemctl --user restart openclaw-gateway

# Wait ~20 seconds for the Pi (faster on beefier hardware)
sleep 20
openclaw gateway status

You should see RPC probe: ok and everything works again.

The Fix (macOS)

Same idea, different file location and restart commands.

Check if they match:

# Get the token from openclaw.json
python3 -c "import json; c=json.load(open('$HOME/.openclaw/openclaw.json')); print(c['gateway']['auth']['token'])"

# Get the token from the launchd plist
grep -A1 OPENCLAW_GATEWAY_TOKEN ~/Library/LaunchAgents/ai.openclaw.gateway.plist

Note: If you don’t have ai.openclaw.gateway.plist, check for the legacy name: com.openclaw.gateway.plist. You can find yours with: ls ~/Library/LaunchAgents/ | grep -i openclaw

If the tokens don’t match, edit the plist:

# Edit the plist
nano ~/Library/LaunchAgents/ai.openclaw.gateway.plist

# Find the OPENCLAW_GATEWAY_TOKEN entry and replace the value
# with the token from openclaw.json

# Unload and reload the service
launchctl unload ~/Library/LaunchAgents/ai.openclaw.gateway.plist
launchctl load ~/Library/LaunchAgents/ai.openclaw.gateway.plist

# Verify
openclaw gateway status

You should see RPC probe: ok.

Why This Happens

Best I can tell, OpenClaw rotates or regenerates the gateway token in openclaw.json during certain operations (updates, config changes, doctor --fix), but doesn’t always update the service file (systemd or launchd) to match.

At the moment, this is a known issue in version 2026.2.15.

Could be fixed tomorrow, but for now this will get you squared away.

Quick Diagnostic One-Liner

Linux

JSON_TOKEN=$(python3 -c "import json; c=json.load(open('$HOME/.openclaw/openclaw.json')); print(c['gateway']['auth']['token'])")
SERVICE_TOKEN=$(grep -oP 'OPENCLAW_GATEWAY_TOKEN=\K.*' ~/.config/systemd/user/openclaw-gateway.service)
[ "$JSON_TOKEN" = "$SERVICE_TOKEN" ] && echo "✅ Tokens match" || echo "❌ Tokens DON'T match — that's your problem"

macOS

JSON_TOKEN=$(python3 -c "import json; c=json.load(open('$HOME/.openclaw/openclaw.json')); print(c['gateway']['auth']['token'])")
PLIST_TOKEN=$(grep -A1 OPENCLAW_GATEWAY_TOKEN ~/Library/LaunchAgents/ai.openclaw.gateway.plist | tail -1 | sed 's/.*<string>\(.*\)<\/string>.*/\1/')
[ "$JSON_TOKEN" = "$PLIST_TOKEN" ] && echo "✅ Tokens match" || echo "❌ Tokens DON'T match — that's your problem"

Hope this saves someone a few hours.

This page may contain affiliate links. Please see my affiliate disclaimer for more info.

Related Posts

View All Posts »
AI Model Parameters Explained: 2B vs 7B vs 40B and Beyond

AI Model Parameters Explained: 2B vs 7B vs 40B and Beyond

What does it mean when an open source AI model has 2B, 7B, or 40B parameters? Learn how parameter count affects performance, hardware needs, and what developers and homelabbers should know before downloading and running these models.