Want AI training or help? Learn OpenClaw 1:1 or train your team — remote, worldwide. See training →
View on Amazon →
💻 Running OpenClaw locally? MINIMUM MacBook Pro M-series (24 GB) ↗ RECOMMENDED Premium Mac for 48 GB+ ↗
← Back to Blog

Fix OpenClaw "gateway token missing" & "1008 unauthorized"

A deep-dive on the single most common OpenClaw error: gateway token auth failures. Part of the OpenClaw troubleshooting hub.

Stuck on this? Get 1:1 OpenClaw help

Remote setup, troubleshooting, and training. See how it works →

If you see disconnected (1008): unauthorized: gateway token missing or unauthorized gateway token mismatch, the client connecting to your gateway is not presenting the exact token the gateway is enforcing. The fix is two commands: read the current token with openclaw config get gateway.auth.token (or mint one with openclaw doctor --generate-gateway-token), then paste that exact value into the Control UI. If you run OpenClaw in Docker, also check that OPENCLAW_GATEWAY_TOKEN isn’t overriding your config. The rest of this post explains the why so it doesn’t keep coming back.

This is the single most common error people hit when they first stand up OpenClaw, on both macOS and Linux. It looks scary because of the raw WebSocket close code, but it’s almost always a token that lives in one place but not another.

The two errors and what each one means

There are two distinct failure modes, and the wording tells you which one you have.

disconnected (1008): unauthorized: gateway token missing
unauthorized gateway token mismatch
  • “gateway token missing” means the client connected to the gateway but presented no token at all. The gateway closed the WebSocket with code 1008 (the policy-violation close code). This is what you get on a fresh install where the Control UI was never given the token, or after you cleared browser storage.
  • “gateway token mismatch” means the client did present a token, but it wasn’t equal to the one the gateway is currently enforcing. This is what you get after you regenerate a token and update it in one place but not everywhere.

Same root cause (token auth), two different states. Knowing which one you have saves time: missing means “nothing is set here,” mismatch means “the wrong thing is set here.”

Why the gateway enforces a token at all (even on localhost)

The OpenClaw gateway is a daemon listening on port 18709. Every client, the Control UI in your browser, the CLI, channel connectors, talks to it over an authenticated WebSocket. The token is the shared secret that proves a client is allowed to drive your agent.

The part that surprises people: the gateway enforces token auth by default even for loopback connections. There is no “it’s just localhost, skip the check” bypass. That’s deliberate. The gateway can run shell commands, control apps, and act on your messaging channels. Without auth, any other process on your machine, or any random browser tab, could open a WebSocket to 127.0.0.1:18709 and start issuing commands. The token closes that hole. So yes, the Control UI still needs the token even when the gateway, the model, and the browser are all on the same Mac.

Once you internalize “the token is mandatory and must match exactly, everywhere,” every variant of this error becomes obvious.

The full fix sequence

Work through these in order. Most setups are fixed by step 2.

1. Read the token the gateway is actually enforcing

# Retrieve the current gateway token
openclaw config get gateway.auth.token

If this prints a long token string, that’s the value every client must present. Copy it exactly, no leading/trailing spaces. If it prints nothing (empty), you have no token configured, which is why you’re seeing missing. Go to step 2 to generate one.

2. Generate a token if none exists

# Mint a fresh gateway token
openclaw doctor --generate-gateway-token

# Make the gateway pick up the new value
openclaw gateway restart

openclaw doctor --generate-gateway-token writes a token into gateway.auth.token. Restart the gateway so it enforces the new value, then re-run openclaw config get gateway.auth.token to confirm what got written.

3. Paste the token into the Control UI

Open the OpenClaw dashboard, go into the Control UI settings, and paste the token from step 1 or 2 into the gateway token field. This is the step people skip during the onboarding wizard, the token scrolls past, they hit continue, and the UI never gets it, which produces the missing error on the very first connect.

4. Verify the connection

# Gateway daemon + RPC health
openclaw gateway status

# Full health report
openclaw status --all

# Watch the live connection in real time
openclaw logs --follow

With openclaw logs --follow running, reconnect the Control UI. You’ll see either a clean connect or the exact close code, which confirms whether the token now matches.

5. If you run in Docker, check the env override

This is the one that causes the “I fixed it but it reverted” loop. In Docker, the OPENCLAW_GATEWAY_TOKEN environment variable takes precedence over the config file. If it’s set in docker-compose.yml, the gateway uses that value on every start, so your openclaw config set edits look like they get ignored.

# Check whether Docker env is overriding your config
docker exec <container_name> env | grep OPENCLAW

If OPENCLAW_GATEWAY_TOKEN is present and differs from what the Control UI has, you have two clean options: make the Control UI present that env value, or remove the env var from docker-compose.yml and let the config file be the single source of truth. Don’t run with both set to different values, that’s exactly the mismatch error.

Regenerating a token: propagate it to EVERY client

Here’s the trap that turns a one-minute fix into an hour. A token is a shared secret. When you regenerate it, the gateway immediately starts enforcing the new value, and every client still holding the old one is instantly rejected with a mismatch. Regeneration is not “change it here,” it’s “change it everywhere, atomically.”

After running openclaw doctor --generate-gateway-token and openclaw gateway restart, walk this list and update each place the token lives:

  • The Control UI in your browser, paste the new token into settings.
  • The Docker env var OPENCLAW_GATEWAY_TOKEN, in docker-compose.yml or wherever you set it, if you use it.
  • Any other browser/device that has the dashboard open, each has its own copy in storage.
  • Channel connectors and scripts, anything that talks to the gateway programmatically and carries the token.

Miss any one of these and that client throws the mismatch error while everything else works, which is genuinely confusing to debug. The rule: regenerate, restart, then propagate to all clients before you test.

Quick reference

Symptom Most likely cause First command
1008: gateway token missingControl UI never got the tokenopenclaw config get gateway.auth.token
gateway token mismatchRegenerated token not propagatedopenclaw doctor --generate-gateway-token
Config edits "revert" in DockerOPENCLAW_GATEWAY_TOKEN overriding configdocker exec <container> env | grep OPENCLAW
Empty token outputNo token configured yetopenclaw doctor --generate-gateway-token

Still failing? Checklist

If you’ve done the fix sequence and it still rejects you, work through these:

  • Did you restart the gateway after changing the token? Config changes to gateway.auth.token only take effect after openclaw gateway restart. The running daemon enforces the value it loaded at startup.
  • Are there whitespace or quote artifacts? Copying from a terminal can pull in a trailing newline or stray quote. Re-run openclaw config get gateway.auth.token and copy from a clean source.
  • Is the gateway even running? Run openclaw gateway status. A missing-style failure can also appear if the client is reaching the wrong thing. Confirm the daemon is healthy on port 18709.
  • Is gateway.bind what you expect? Run openclaw config get gateway.mode and openclaw config get gateway.bind. If a remote client is connecting but the gateway is bound to loopback, that’s a separate connectivity problem, not the token, but it can masquerade as auth trouble.
  • Multiple gateways? If a stale daemon is still listening on 18709 with the old token, a fresh client will mismatch against it. See the port-conflict section in the troubleshooting hub (openclaw gateway restart, then openclaw gateway install --force if it’s stuck).
  • Docker still winning? Re-check docker exec &lt;container_name&gt; env | grep OPENCLAW. If the env var is set, it wins over config every single time, no exceptions.

If you’ve confirmed the token is identical in the config, the Control UI, and the Docker env, and the gateway has been restarted, you should connect cleanly. Use openclaw logs --follow during the reconnect to watch the handshake succeed or fail in real time.

For the full set of OpenClaw errors, port conflicts, blank responses, channel issues, and model defaults, see the OpenClaw troubleshooting guide. If you’re still picking hardware or a model, the best local models guide and best local LLM by RAM cover that.

Need help?

If you’ve worked through all of this and the gateway still won’t accept your token, we offer remote setup and 1:1 troubleshooting. See how OpenClaw training works →

Get guides like this in your inbox every Wednesday.

No spam. Unsubscribe anytime.

You'll probably need this again.

Press Cmd+D (Mac) or Ctrl+D (Windows) to bookmark this page.

Want to learn OpenClaw properly?

We do remote 1:1 and team training, setup, and troubleshooting worldwide.

See Training Options

Read next

OpenClaw Returns Blank or Empty Responses? Here's the Fix
OpenClaw replies with an empty bubble or no reply at all? The 5-step diagnostic and the 4 real causes: model unreachable, channel down, context too large, model starved for RAM.
OpenClaw Keeps Using Claude Instead of Your Local Ollama Model — Fix
OpenClaw keeps calling Claude/Anthropic even though you set up Ollama? Fix the default chat model, kill env overrides, and verify with openclaw models status.
Fix OpenClaw "timed out waiting for gateway port 18709"
Fix OpenClaw "timed out after 60s waiting for gateway port 18709", EADDRINUSE, and "another gateway instance already listening" with a clear command sequence.