#how to change gateway so i can access the dashboard

118 messages Ā· Page 1 of 1 (latest)

high steeple
#

So my dashboard on my vm now sets at 127.0.0.1, i wat to change it into my normal IP address(its private so no worries)
im lost as to finding where is the config location, can anyone help me in this issue?
os : debian 12

whole snowBOT
solar solsticeBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> āœ… Mark Solution

whole snowBOT
wicked shardBOT
#

First, can you paste openclaw --version?

On current builds, the config is usually here:

~/.openclaw/openclaw.json

To print the exact active path on your VM:

openclaw config file

If you want the gateway to listen on your VM’s LAN/private IP instead of 127.0.0.1, the key to change is gateway.bind, usually to lan:

#
openclaw config set gateway.bind '"lan"' --strict-json

If you want the dashboard/Control UI from another browser/device, also set the allowed origin to your actual URL:

openclaw config set gateway.controlUi.allowedOrigins '["http://YOUR_VM_IP:18789"]' --strict-json

Then restart:

openclaw gateway restart
openclaw gateway status
#

A couple important gotchas:

  • the config format is JSON5, not YAML
  • plain http://<private-ip>:18789 can still be awkward for the Control UI because it is a non-secure browser context
  • safest/recommended remote setup is Tailscale Serve or an HTTPS reverse proxy

Docs:

If you paste your openclaw --version and openclaw gateway status, I can tell you the exact commands for your setup.

high steeple
#

if say my interface is ens18, should i set it as "openclaw config set gateway.bind '"ens18"' --strict-json" ?

wicked shardBOT
#

Nope, not the interface name.

gateway.bind only wants a bind mode, like:

  • "loopback" = 127.0.0.1 only
  • "lan" = all interfaces (0.0.0.0)
  • "tailnet"
  • "custom" = specific IP via gateway.customBindHost

So for your case, usually do:

openclaw config set gateway.bind '"lan"' --strict-json

Or, if you want one specific IP only:

#
openclaw config set gateway.bind '"custom"' --strict-json
openclaw config set gateway.customBindHost '"192.168.x.x"' --strict-json

Not this:

openclaw config set gateway.bind '"ens18"' --strict-json

Then restart:

openclaw gateway restart
#

And if you’re opening the dashboard from another device/browser, also set:

openclaw config set gateway.controlUi.allowedOrigins '["http://192.168.x.x:18789"]' --strict-json

One warning, http://private-ip:18789 is still plain HTTP, so the Control UI can be annoying there. HTTPS via Tailscale Serve or a reverse proxy is the cleaner setup.

If you want, paste your VM IP and I’ll write the exact 3 commands for it.

high steeple
#

the ip is 10.255.254.222
and after i tried the commands, it shows this .

Start with: openclaw gateway install
Start with: openclaw gateway
Start with: systemctl --user start openclaw-gateway.service

I did the gateway install and it shows this :

wicked shardBOT
#

Ah, got it, this is now a service/systemd problem, not a bind-config problem.

Your bind config should be one of these, for your IP 10.255.254.222:

openclaw config set gateway.bind '"custom"' --strict-json
openclaw config set gateway.customBindHost '"10.255.254.222"' --strict-json
openclaw config set gateway.controlUi.allowedOrigins '["http://10.255.254.222:18789"]' --strict-json

But the reason it still is not up is this part:

systemctl daemon-reload failed: Transport endpoint is not connected

That usually means your systemd user session is unavailable/broken on the VM.

#

Try this:

openclaw --version
systemctl --user status
sudo loginctl enable-linger "$(whoami)"
loginctl show-user "$(whoami)" -p Linger

Then log out and back in, or reboot the VM once, and retry:

systemctl --user daemon-reload
openclaw gateway install
systemctl --user start openclaw-gateway.service
openclaw gateway status
#

If you just want to test immediately without fighting systemd yet, run it in the foreground:

openclaw gateway

Then try opening:

http://10.255.254.222:18789/

Two notes:

  • systemctl --user needs a healthy user systemd session
  • http://10.255.254.222:18789 is still plain HTTP, so Control UI/browser auth can still be annoying there. HTTPS via Tailscale Serve or a reverse proxy is cleaner.
#

If you paste the output of:

systemctl --user status
openclaw gateway status
openclaw --version

I can tell you the exact next step.

high steeple
#

cmd = systemctl --user status
result =
Failed to connect to bus: Operation not permitted

wicked shardBOT
#

Yep, that confirms it, your systemd user bus is unavailable.

So openclaw gateway install will keep failing until that is fixed.

Try this first:

sudo loginctl enable-linger "$(whoami)"
export XDG_RUNTIME_DIR=/run/user/$(id -u)
systemctl --user status

If systemctl --user status starts working after that, then do:

openclaw gateway install
#
systemctl --user start openclaw-gateway.service
openclaw gateway status

If it still says Failed to connect to bus / Operation not permitted, then don’t use the service installer on this VM for now. Just run the gateway directly:

openclaw gateway

And keep that terminal open.

For your IP, the config should be:

#
openclaw config set gateway.bind '"custom"' --strict-json
openclaw config set gateway.customBindHost '"10.255.254.222"' --strict-json
openclaw config set gateway.controlUi.allowedOrigins '["http://10.255.254.222:18789"]' --strict-json

Important caveat: http://10.255.254.222:18789 is still plain HTTP, so the Control UI may still be fussy. The cleaner remote setup is HTTPS via Tailscale Serve or a reverse proxy.

If you want, next paste these:

loginctl show-user "$(whoami)" -p Linger
echo "$XDG_RUNTIME_DIR"
openclaw --version

and I can tell you whether this is a headless-systemd issue or a restricted VM/container issue.

#

Glad that helped! šŸŽ‰
If this fixed it, please right-click the solution message → Apps → āœ… Mark Solution.
This helps Answer Overflow index the solution for future users.

high steeple
#

it shows me this


šŸ¦ž OpenClaw 2026.4.14 (323493f) — I keep secrets like a vault... unless you print them in debug logs again.

│
ā—‡
00:19:30 [gateway] loading configuration…
00:19:30 [gateway] resolving authentication…
00:19:30 [gateway] starting...
00:19:39 [gateway] starting HTTP server...
00:19:39 [canvas] host mounted at http://10.255.254.222:18789/__openclaw__/canvas/ (root /root/.openclaw/canvas)
00:19:39 [gateway] āš ļø  Gateway is binding to a non-loopback address. Ensure authentication is configured before exposing to public networks.
a00:19:41 Gateway failed to start: another gateway instance is already listening on ws://10.255.254.222:18789 | listen EADDRINUSE: address already in use 10.255.254.222:18789
If the gateway is supervised, stop it with: openclaw gateway stop
00:19:41 Port 18789 is already in use.
00:19:41 - pid 642 root: openclaw-gateway (10.255.254.222:18789)
00:19:41 - Gateway already running locally. Stop it (openclaw gateway stop) or use a different port.

I did rebooted it after changing the loginctl

wicked shardBOT
#

Nice, this is actually good news.

Your bind change worked. The important line is:

pid 642 root: openclaw-gateway (10.255.254.222:18789)

So a gateway is already running on 10.255.254.222:18789.
Your second openclaw gateway failed only because the port was already in use.

A couple important takeaways:

  • your active OpenClaw user is probably root
  • so the config path is likely:
#
/root/.openclaw/openclaw.json

You can confirm with:

openclaw config file
openclaw gateway status

So at this point, try opening:

http://10.255.254.222:18789/
#

If you want to restart the existing one first, stop the current instance as the same user that owns it (looks like root):

openclaw gateway stop

Then start again if needed:

openclaw gateway

One more thing, since it’s running on plain http://10.255.254.222, you may still hit a Control UI auth / secure-context issue even though the gateway is listening correctly.

So the next question is:

  • does the page open at all
#
  • or does it open but fail to connect / say unauthorized / origin not allowed

Paste what the browser shows and I can tell you the final step.

Glad that helped! šŸŽ‰
If this fixed it, please right-click the solution message → Apps → āœ… Mark Solution.
This helps Answer Overflow index the solution for future users.

silver dew
#

Instead of exposing it to your lan, i would use tailscale serve. i have mine on a proxmox vm and i tried doing this too and it worked but then i hit some error i forgot what it was but setting up tailscale serve has worked with no issues for months

wicked shardBOT
#

Yep, I’d recommend that too.

Your current bind change seems to be working, but plain http://10.255.254.222:18789 is exactly the setup that tends to hit Control UI browser/auth weirdness.

Cleaner path:

openclaw config set gateway.bind '"loopback"' --strict-json
openclaw gateway --tailscale serve

Then open:

https://<your-magicdns-name>/
high steeple
#

alright, will it work with private ip? its nat-ed to a public ip. if yes, can you show me how to set it up?

wicked shardBOT
#

Yep, Tailscale Serve works fine behind NAT/private IP. That’s actually one of the main reasons to use it.

The important bit is: don’t keep gateway.bind on your private IP for this.
For Tailscale Serve, put it back on loopback and let Tailscale do the HTTPS/public-facing part.

Quick setup

Run these as the same user that owns the gateway on that VM, which looks like root from your earlier output.

  1. Make sure Tailscale is installed and logged in:
tailscale status
  1. Switch OpenClaw back to loopback + enable Serve:
#
openclaw config set gateway.bind '"loopback"' --strict-json
openclaw config set gateway.tailscale.mode '"serve"' --strict-json
  1. Stop the existing gateway, then start it with Serve:
openclaw gateway stop
openclaw gateway --tailscale serve
  1. Find your MagicDNS name:
tailscale status
#

Then open:

https://<your-magicdns-name>/

Notes

  • tailscale serve gives you HTTPS, which avoids the plain-HTTP Control UI issues
  • default Tailscale Serve auth behavior is usually fine for dashboard access
  • if your gateway is running as root, the config is probably under:
/root/.openclaw/openclaw.json

If you want the shortest ā€œdoes it work?ā€ test

silver dew
#

create an account on tailscale its basically like a free private vpn for your own devices. you just need to install it on the vm and then also on the devices you want to remote access it from. thsi even lets you access the gateway through your phone. then just log in to your account on each device. when you turn it on youll have that device "join" the same network as the others on a private network.

wicked shardBOT
#

Yep, that’s the idea.

Tiny OpenClaw-specific nuance: once Tailscale is set up, keep the gateway on loopback and use Tailscale Serve for the dashboard, instead of binding OpenClaw directly to the LAN IP.

That gives you:

  • HTTPS
  • tailnet-only access
  • fewer Control UI auth/browser headaches
  • access from phone/laptop if they’re on the same tailnet

OpenClaw docs for that path:

If AmatoMasaki wants, the next thing to paste is just:

#
tailscale status

and we can verify the exact URL/setup.

high steeple
#

tailscale status
100.123.7.13 openclaw-dimas dimaswalker441@ linux -
100.65.229.87 desktop-ctmc2vs dimaswalker441@ windows idle, tx 892 rx 884

wicked shardBOT
#

Nice, Tailscale is up on both devices, so yes, this should work.

From the VM, run these as the same user that owns the gateway:

openclaw config set gateway.bind '"loopback"' --strict-json
openclaw config set gateway.tailscale.mode '"serve"' --strict-json
openclaw gateway stop
openclaw gateway --tailscale serve

Then check:

tailscale serve status
#

After that, open the HTTPS Serve URL from your Windows machine.
Do not use the raw private IP or tailnet IP for the dashboard if you’re using Serve.

A few notes:

  • your VM Tailscale device is openclaw-dimas
  • your Windows device is already on the same tailnet
  • NAT/private IP does not matter here, that’s exactly what Tailscale is good at

If openclaw gateway --tailscale serve does not print the URL clearly, paste the output of:

tailscale serve status

and I’ll tell you the exact address to open.

high steeple
#

it shows no serve config

wicked shardBOT
#

Got it, that means Serve was never actually registered.

Most likely one of these happened:

  • the old gateway on port 18789 was still running
  • you ran the command as a different user than the one owning the gateway
  • openclaw gateway --tailscale serve exited before it could configure Tailscale

From your earlier logs, the gateway looked root-owned, so do this as that same user:

openclaw gateway stop
openclaw config get gateway.bind
openclaw config get gateway.tailscale.mode
openclaw gateway --tailscale serve
#

Then, in a second terminal:

tailscale serve status

You should not see no serve config after that if it started correctly.

Important: just setting

gateway.tailscale.mode = "serve"

in config is not enough by itself for the already-running old process. You need to restart/start the gateway so it actually sets up Serve.

If it still says no serve config, paste the full output of:

#
openclaw gateway --tailscale serve

That output will tell us exactly what part failed.

high steeple
#

no serve config, still the same.

openclaw config get gateway.bind
openclaw config get gateway.tailscale.mode
openclaw gateway --tailscale serve

šŸ¦ž OpenClaw 2026.4.14 (323493f) — WhatsApp automation without the "please accept our new privacy policy".

Gateway service disabled.

šŸ¦ž OpenClaw 2026.4.14 (323493f) — Welcome to the command line: where dreams compile and confidence segfaults.

loopback

šŸ¦ž OpenClaw 2026.4.14 (323493f) — I'm like tmux: confusing at first, then suddenly you can't live without me.

serve

šŸ¦ž OpenClaw 2026.4.14 (323493f) — Your AI assistant, now without the $3,499 headset.

│
ā—‡
00:57:48 [gateway] loading configuration…
00:57:48 [gateway] resolving authentication…
00:57:48 [gateway] starting...
00:57:53 Gateway failed to start: gateway already running (pid 13946); lock timeout after 5000ms
If the gateway is supervised, stop it with: openclaw gateway stop
00:57:53 Port 18789 is already in use.
00:57:53 - pid 13946 root: openclaw-gateway (127.0.0.1:18789)
00:57:53 - Gateway already running locally. Stop it (openclaw gateway stop) or use a different port.
wicked shardBOT
#

Aha, I think I see the real problem now.

You’re almost certainly editing one user’s OpenClaw config, while the actual running gateway belongs to root.

This line is the giveaway:

pid 13946 root: openclaw-gateway (127.0.0.1:18789)

So right now:

  • your openclaw config get ... is likely reading your user config
  • but the live gateway is a different root-owned instance
  • that’s why gateway stop says disabled, but the port is still taken
  • and that’s why Tailscale Serve never appears
#

Recommendation

Pick one user and stick with it.
Honestly, I’d avoid running OpenClaw as root unless you really mean to.

Best path

  1. Find which user you are currently using:
whoami
openclaw config file
  1. Check the root-owned config too:
#
sudo openclaw config file
sudo openclaw config get gateway.bind
sudo openclaw config get gateway.tailscale.mode

If those values are different, that’s the issue.

If you want to keep using the root-owned gateway

Run the setup as root instead:

sudo openclaw gateway stop
sudo openclaw config set gateway.bind '"loopback"' --strict-json
sudo openclaw config set gateway.tailscale.mode '"serve"' --strict-json
#
sudo openclaw gateway --tailscale serve
tailscale serve status

If you want the cleaner setup

Stop/disable the root-owned instance, then run OpenClaw only as your normal user.

That’ll save you a lot of headaches later.

Right now, the next most useful thing to paste is:

whoami
openclaw config file
#
sudo openclaw config file
sudo openclaw config get gateway.bind
sudo openclaw config get gateway.tailscale.mode

I’m pretty sure that’ll confirm the split-user config problem.

high steeple
#

sudo openclaw config file
sudo openclaw config get gateway.bind
sudo openclaw config get gateway.tailscale.mode

šŸ¦ž OpenClaw 2026.4.14 (323493f) — Making 'I'll automate that later' happen now.

~/.openclaw/openclaw.json

šŸ¦ž OpenClaw 2026.4.14 (323493f) — I'll refactor your busywork like it owes me money.

loopback

šŸ¦ž OpenClaw 2026.4.14 (323493f) — Deployed locally, trusted globally, debugged eternally.
serve

wicked shardBOT
#

Yep, that output is pretty telling.

sudo openclaw config get gateway.tailscale.mode should have printed serve if it was set in the active/root context. Since it didn’t, that’s likely the missing piece.

I’d do the next part in a real root shell so there’s no sudo/home weirdness:

sudo -i
openclaw config set gateway.bind '"loopback"' --strict-json
openclaw config set gateway.tailscale.mode '"serve"' --strict-json
openclaw config get gateway.bind
openclaw config get gateway.tailscale.mode

You want those to print:

#
loopback
serve

Then stop and start the root-owned gateway again:

openclaw gateway stop
openclaw gateway --tailscale serve
tailscale serve status

If openclaw gateway stop still does not stop the running root gateway, paste this next:

#
ps -fp 13946

because then we need to see how that root process is being started.

So, short version: I think you’re very close now, the root-owned gateway just doesn’t have tailscale.mode=serve yet.

high steeple
#

it shows serve now, whats next?

wicked shardBOT
#

Nice, perfect. Now do this:

openclaw gateway stop
openclaw gateway --tailscale serve

Then in another terminal:

tailscale serve status

What you want now is a real Serve entry, not no serve config.

After that, open the HTTPS Tailscale URL from your Windows machine, not the private IP.

#

So the flow is:

  1. stop old gateway
  2. start gateway with Serve
  3. check tailscale serve status
  4. open the HTTPS Serve URL on your other device

If openclaw gateway stop does not actually stop it, paste the output and I’ll give you the exact next step.

high steeple
#

its kinda stuck on
01:06:06 [plugins] embedded acpx runtime backend ready
should i be worried?

wicked shardBOT
#

Nah, not by itself.

That line is not an error, it just means one backend finished initializing.

I’d only worry if it sits there for 30 to 60 seconds with no more output.

While it’s running, open a second terminal and check:

tailscale serve status
openclaw gateway status

If tailscale serve status now shows a Serve entry, you’re probably fine.

So:

#
  • that line alone is okay
  • wait a little
  • check tailscale serve status

If it still looks frozen after a minute, paste the next lines after that or the output of those two commands.

high steeple
#

kinda suck over a minute now

#

stuck*

wicked shardBOT
#

Yeah, over a minute is too long. Let’s check it instead of waiting.

Keep that terminal open, then in a second terminal run:

openclaw gateway status
tailscale serve status

If that doesn’t make it obvious, also run:

openclaw logs --follow

What I’m trying to separate is:

#
  • gateway is actually up, but the foreground command looks stuck
  • gateway is not up
  • Tailscale Serve never attached

If openclaw gateway status says running and tailscale serve status shows a Serve route, you’re probably okay.

If not, paste the outputs of:

openclaw gateway status
tailscale serve status

and I’ll tell you the next move.

high steeple
#

openclaw gateway status
tailscale serve status

šŸ¦ž OpenClaw 2026.4.14 (323493f) — I can grep it, git blame it, and gently roast it—pick your coping mechanism.

│
ā—‡
Service: systemd (disabled)
File logs: /tmp/openclaw/openclaw-2026-04-15.log
Command: /usr/bin/node /usr/lib/node_modules/openclaw/dist/index.js gateway --port 18789
Service file: ~/.config/systemd/user/openclaw-gateway.service
Service env: OPENCLAW_GATEWAY_PORT=18789

Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json

Gateway: bind=loopback (127.0.0.1), port=18789 (service args)
Probe target: ws://127.0.0.1:18789
Dashboard: http://127.0.0.1:18789/
Probe note: Loopback-only gateway; only local clients can connect.

Runtime: unknown (Failed to get properties: Transport endpoint is not connected)
RPC probe: ok

Listening: 127.0.0.1:18789
Troubles: run openclaw status
Troubleshooting: https://docs.openclaw.ai/troubleshooting
No serve config

wicked shardBOT
#

This is actually a useful clue.

Your gateway is not dead, it’s up:

  • RPC probe: ok
  • Listening: 127.0.0.1:18789

So the foreground command is basically just running the gateway.

The real problem is only this part:

No serve config

That means the Tailscale Serve step never attached.

#

Next step, from another terminal, run:

openclaw logs --follow

and look for anything mentioning:

  • tailscale
  • serve
  • https
  • cert
  • MagicDNS

Then paste those lines here.

So, short version:

#
  • gateway itself is healthy
  • Serve is the only broken part
  • logs should tell us why

Tailscale Serve also needs the normal prerequisites on the tailnet side, especially HTTPS/MagicDNS support, so I’m suspicious that’s what we’re about to find.

high steeple
#

18:16:12+00:00 error gateway connect failed: GatewayClientRequestError: pairing required
18:16:12+00:00 error gateway connect failed: GatewayClientRequestError: pairing required
gateway connect failed: GatewayClientRequestError: pairing required
18:16:12+00:00 warn gateway/ws {"subsystem":"gateway/ws"} {"cause":"pairing-required","handshake":"failed","durationMs":17,"lastFrameType":"req","lastFrameMethod":"connect","lastFrameId":"228b1866-f666-40c4-a8ea-bbfa2d4151fd","host":"127.0.0.1:18789","remoteAddr":"127.0.0.1","remotePort":45670,"localAddr":"127.0.0.1","localPort":18789,"endpoint":"127.0.0.1:45670->127.0.0.1:18789","deviceId":"fa49969d681d2b746569cac037fbc5a8fd3b450bbd9706cfa85153c26ebbcdc6","requestId":"42639603-3890-4cf7-b957-76aa45ae7b1f","reason":"scope-upgrade"} closed before connect conn=69ebc3cf-d263-4fda-a583-388d484c7422 peer=127.0.0.1:45670->127.0.0.1:18789 remote=127.0.0.1 fwd=n/a origin=n/a host=127.0.0.1:18789 ua=n/a code=1008 reason=connect failed
18:16:13+00:00 warn gateway {"subsystem":"gateway"} security audit: device access upgrade requested reason=scope-upgrade device=fa49969d681d2b746569cac037fbc5a8fd3b450bbd9706cfa85153c26ebbcdc6 ip=unknown-ip auth=password roleFrom=operator roleTo=operator scopesFrom=operator.read scopesTo=operator.admin,operator.approvals,operator.pairing,operator.read,operator.talk.secrets,operator.write client=cli conn=0c319b96-1571-45c5-b7e6-ffe979619ba1
18:16:13+00:00 error gateway connect failed: GatewayClientRequestError: pairing required
18:16:13+00:00 error gateway connect failed: GatewayClientRequestError: pairing required
gateway connect failed: GatewayClientRequestError: pairing required

wicked shardBOT
#

Aha, there it is. This is the real blocker:

pairing required
reason=scope-upgrade
requestId=42639603-3890-4cf7-b957-76aa45ae7b1f

So it’s not stuck, and it’s not really a Tailscale problem.
Your CLI/device is asking the gateway for higher operator scopes, and the gateway wants you to approve that upgrade.

Run this on the VM, as the same user/context you’re using for OpenClaw:

openclaw devices list
openclaw devices approve 42639603-3890-4cf7-b957-76aa45ae7b1f
#

Then rerun:

openclaw gateway --tailscale serve
tailscale serve status

If the request ID changed, use the new one from openclaw devices list.

So yeah, good news, we finally found the real issue 😌
It’s a device pairing/scope approval step.

If you want, paste the output of openclaw devices list next and I’ll point to the exact entry.

high steeple
#

01:19:09 [gateway] loading configuration…
01:19:09 [gateway] resolving authentication…
01:19:09 [gateway] starting...
01:19:14 [gateway] starting HTTP server...
01:19:14 [canvas] host mounted at http://127.0.0.1:18789/__openclaw__/canvas/ (root /root/.openclaw/canvas)
01:19:14 [health-monitor] started (interval: 300s, startup-grace: 60s, channel-connect-grace: 120s)
01:19:15 [gateway] agent model: openai/gpt-5.4
01:19:15 [gateway] ready (5 plugins: acpx, browser, device-pair, phone-control, talk-voice; 5.7s)
01:19:15 [gateway] log file: /tmp/openclaw/openclaw-2026-04-15.log
01:19:30 [tailscale] serve failed: Command failed: /usr/bin/tailscale serve --bg --yes 18789

01:19:30 [gateway] starting channels and sidecars...
01:19:30 [hooks] loaded 4 internal hook handlers
01:19:30 [plugins] embedded acpx runtime backend registered (cwd: /root/.openclaw/workspace)
01:19:30 [browser/server] Browser control listening on http://127.0.0.1:18791/ (auth=password)
01:19:31 [heartbeat] started
01:19:31 [plugins] embedded acpx runtime backend ready
should i be worried?

wicked shardBOT
#

Nope, not about the gateway itself, this part is actually fine:

[gateway] ready

The only failing bit is this:

[tailscale] serve failed: /usr/bin/tailscale serve --bg --yes 18789

So now we should debug Tailscale directly, not OpenClaw.

Run this manually and paste the exact error:

#
tailscale serve --bg --yes 18789

Also run:

tailscale serve status
tailscale version

Most likely causes are:

  • Tailscale Serve prerequisites not enabled yet
  • HTTPS/MagicDNS issue on the tailnet
  • Tailscale CLI/version quirk
#

So, short version:

  • gateway is healthy
  • Tailscale Serve is failing
  • the next clue will come from running tailscale serve --bg --yes 18789 directly

Paste that output and we can finish this off.

high steeple
#

ailscale serve status
tailscale version
https://openclaw-xxxxxx.ts.net (tailnet only) [redacted because privacy]
|-- / proxy http://127.0.0.1:18789

1.96.4
tailscale commit: 8cf541dfd1e0a97096c01cb775d5e26336f3bc6c
long version: 1.96.4-t8cf541dfd-g62bc84ce7
other commit: 62bc84ce7236dafdeb40272171dae03a66502ed1
go version: go1.26.1

wicked shardBOT
#

Nice, that means it’s working now šŸŽ‰

This part confirms it:

https://openclaw-xxxxxx.ts.net
|-- / proxy http://127.0.0.1:18789

So the setup is now:

  • OpenClaw stays on loopback (127.0.0.1)
  • Tailscale Serve exposes it safely over HTTPS
  • you should open the https://openclaw-xxxxxx.ts.net URL from your Windows machine (or phone) while signed into the same tailnet

So yes, you do not need to expose your private IP anymore.

#

If the page opens but asks for auth, use your normal gateway auth/token/password.
If it just opens cleanly, even better.

At this point I’d test the URL from your other device and you should be good.

Glad we got there 😌
If this fixed it, please right-click the solution message → Apps → āœ… Mark Solution.
This helps Answer Overflow index the solution for future users.

high steeple
#

how do i open the dashboard now?

wicked shardBOT
#

Open it in a browser on your Windows PC or phone that is signed into the same Tailscale account/tailnet.

Use the exact URL from:

tailscale serve status

In your case it’ll be the redacted one, basically:

https://openclaw-xxxxxx.ts.net/

So, step by step:

  1. make sure Tailscale is connected on the device you’re using
#
  1. open a browser
  2. go to the https://...ts.net URL from tailscale serve status

If it asks for auth inside the dashboard, use your gateway token/password and hit Connect.

If you want, paste what happens after opening the URL, and I’ll help with the last step.

high steeple
#

hmmm, i opened it from my windows tailscale but it shows nxdomain

wicked shardBOT
#

NXDOMAIN usually means the Tailscale DNS name is not resolving on your Windows machine.

Most likely causes:

  1. you used the redacted/placeholder URL instead of the exact one
  2. MagicDNS is not enabled / not working on the tailnet
  3. Windows Tailscale is connected, but not using Tailscale DNS properly

First, on the VM, copy the exact URL again from:

tailscale serve status

Then on the Windows machine:

  • make sure Tailscale is connected
#
  • open that exact https://...ts.net URL

If it still says NXDOMAIN, then the next likely fix is enable MagicDNS in your Tailscale admin settings, because Serve depends on that DNS name resolving.

So right now I’d check:

  • are you using the exact full .ts.net URL
  • is MagicDNS enabled in Tailscale

If you want, paste the output of tailscale status from the Windows machine next, and we can check whether it’s a client DNS issue.

high steeple
#

tailscale status
100.65.229.87 desktop-ctmc2vs dimaswalker441@ windows -
100.123.7.13 openclaw-dimas dimaswalker441@ linux idle, tx 948 rx 828

#

if say i wanna open it thorough the ip, how?

wicked shardBOT
#

Yep, both devices are on the same tailnet, so that part is fine.

At this point, NXDOMAIN almost certainly means a Tailscale DNS / MagicDNS issue, not an OpenClaw issue.

So the situation is:

  • OpenClaw is up
  • Tailscale Serve is configured
  • both devices are on the tailnet
  • the .ts.net hostname is just not resolving on Windows

Next fix

In the Tailscale admin console, enable MagicDNS for your tailnet.

Then on Windows:

#
  • disconnect/reconnect Tailscale, or restart the Tailscale app
  • try the exact https://...ts.net URL again

If you want to verify it directly on Windows, run:

nslookup your-exact-openclaw-url.ts.net

If that fails, it confirms the DNS side is the problem.

So yeah, I’d stop debugging OpenClaw now, you’re basically at the Tailscale DNS layer.
Once MagicDNS resolves properly, that Serve URL should work.

Glad that helped! šŸŽ‰
If this fixed it, please right-click the solution message → Apps → āœ… Mark Solution.
This helps Answer Overflow index the solution for future users.

#

If you want to open it through an IP instead of the Tailscale .ts.net URL, don’t use Serve mode. Use a direct bind instead.

Best IP-based option: Tailscale IP

Since both devices are already on Tailscale, I’d use the VM’s Tailscale IP:

100.123.7.13

Set it like this:

openclaw config set gateway.tailscale.mode '"off"' --strict-json
openclaw config set gateway.bind '"tailnet"' --strict-json
#

Then restart the gateway, and open:

http://100.123.7.13:18789/

If the dashboard asks for auth, paste your gateway token/password in the UI.

If you want the VM private LAN IP instead

Use your private IP:

10.255.254.222

Config:

#
openclaw config set gateway.tailscale.mode '"off"' --strict-json
openclaw config set gateway.bind '"custom"' --strict-json
openclaw config set gateway.customBindHost '"10.255.254.222"' --strict-json
openclaw config set gateway.controlUi.allowedOrigins '["http://10.255.254.222:18789"]' --strict-json

Then restart and open:

http://10.255.254.222:18789/

My recommendation

  • cleanest: Tailscale Serve URL
  • if you really want IP: use the Tailscale IP (100.123.7.13) rather than the NAT/LAN IP
#

If you want, I can give you the exact final command set for the Tailscale IP path only.

high steeple
wicked shardBOT
#

Ah, that explains it.

Your Windows machine is asking Cloudflare (1.1.1.1), not Tailscale DNS.

So this result:

Server: one.one.one.one

means your Windows client is not using Tailscale DNS, which is why the MagicDNS name returns NXDOMAIN.

So:

  • MagicDNS can be enabled
  • but if the client is still using 1.1.1.1, the .ts.net name still won’t resolve
#

Two ways forward

1. Fix the Windows Tailscale DNS side

Make sure the Windows Tailscale client is allowed to use/manage DNS, then reconnect Tailscale and retry the https://...ts.net URL.

2. Easier path: use the Tailscale IP directly

Since you already asked about IP access, this is probably the fastest route for you.

Use the VM’s Tailscale IP:

100.123.7.13

and switch OpenClaw to tailnet bind:

#
openclaw config set gateway.tailscale.mode '"off"' --strict-json
openclaw config set gateway.bind '"tailnet"' --strict-json

Then restart the gateway and open:

http://100.123.7.13:18789/

If it asks for auth, use your gateway token/password.

Honestly, given your Windows DNS setup, I’d use the Tailscale IP path right now. It’s simpler and avoids fighting MagicDNS.

high steeple
#

origin not allowed (open the Control UI from the gateway host or allow it in gateway.controlUi.allowedOrigins)

wicked shardBOT
#

Yep, that’s the last piece.

OpenClaw is rejecting the browser origin because you’re no longer opening it from localhost.

If you’re opening it via the Tailscale IP, add that exact origin:

openclaw config set gateway.controlUi.allowedOrigins '["http://100.123.7.13:18789"]' --strict-json

If you also want the LAN IP allowed, you can include both:

openclaw config set gateway.controlUi.allowedOrigins '["http://100.123.7.13:18789","http://10.255.254.222:18789"]' --strict-json

Then restart the gateway and open the same URL again.

#

Important: the origin has to match exactly:

  • protocol (http vs https)
  • host/IP
  • port

So if you open:

http://100.123.7.13:18789/

then allowedOrigins must include exactly:

http://100.123.7.13:18789
#

You’re very close now, this is a normal non-localhost Control UI step.

high steeple
#

01:43:52 [ws] closed before connect conn=f92a1af9-a95e-43cc-8b91-b5c75c21e4c7 peer=100.65.229.87:65265->100.123.7.13:18789 remote=100.65.229.87 fwd=n/a origin=http://100.123.7.13:18789 host=100.123.7.13:18789 ua=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 code=1008 reason=control ui requires device identity (use HTTPS or localhost secure context)
01:43:59 [ws] closed before connect conn=b2fc4def-a37b-40b5-9115-655532d1a069 peer=100.65.229.87:61045->100.123.7.13:18789 remote=100.65.229.87 fwd=n/a origin=http://100.123.7.13:18789 host=100.123.7.13:18789 ua=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 code=1008 reason=control ui requires device identity (use HTTPS or localhost secure context)

#

how about it @wicked shard ??

wicked shardBOT
#

Yep šŸ˜„ you’re basically at the finish line.

That origin not allowed error means the gateway is reachable, but the browser origin still isn’t in:

gateway.controlUi.allowedOrigins

So the check now is:

openclaw config get gateway.controlUi.allowedOrigins

If you’re opening from the Tailscale IP, it should contain exactly:

#
["http://100.123.7.13:18789"]

Then restart the gateway and try again.

If you already did that and it still errors, paste these two things:

openclaw config get gateway.controlUi.allowedOrigins

and the exact URL you opened in the browser.

Glad that helped! šŸŽ‰
If this fixed it, please right-click the solution message → Apps → āœ… Mark Solution.
This helps Answer Overflow index the solution for future users.

high steeple
wicked shardBOT
#

That list looks right for IP-based access.

So if you’re still getting origin not allowed, it’s usually one of these:

  1. you didn’t restart the gateway after setting it
  2. you’re opening a different URL than one of those exact two origins
  3. the running gateway is using a different config/user context

So the next two checks are:

openclaw gateway status
sudo openclaw config get gateway.controlUi.allowedOrigins

And also tell me the exact URL you opened in the browser.

#

Because if you opened exactly one of these:

  • http://100.123.7.13:18789/
  • http://10.255.254.222:18789/

and restarted the gateway, then origin not allowed should not happen unless the running process is reading a different config.

high steeple
#

i stopped the gateway, then it shows
šŸ¦ž OpenClaw 2026.4.14 (323493f) — I'll butter your workflow like a lobster roll: messy, delicious, effective.

Gateway service disabled.

then i do openclaw gateway

then it shows this :
openclaw gateway

šŸ¦ž OpenClaw 2026.4.14 (323493f) — Type the command with confidence—nature will provide the stack trace if needed.

│
ā—‡
01:47:44 [gateway] loading configuration…
01:47:44 [gateway] resolving authentication…
01:47:44 [gateway] starting...
01:47:49 [gateway] starting HTTP server...
01:47:49 [canvas] host mounted at http://100.123.7.13:18789/__openclaw__/canvas/ (root /root/.openclaw/canvas)
01:47:49 [gateway] āš ļø Gateway is binding to a non-loopback address. Ensure authentication is configured before exposing to public networks.
01:47:51 Gateway failed to start: another gateway instance is already listening on ws://100.123.7.13:18789 | listen EADDRINUSE: address already in use 100.123.7.13:18789
If the gateway is supervised, stop it with: openclaw gateway stop
01:47:51 Port 18789 is already in use.
01:47:51 - pid 31708 root: openclaw-gateway (100.123.7.13:18789)
01:47:51 - Gateway already running locally. Stop it (openclaw gateway stop) or use a different port.

wicked shardBOT
#

Okay, this explains the weird loop.

You are not stopping the actual running gateway.
You’re only getting:

Gateway service disabled

because there is no managed service, but there is still a live gateway process:

pid 31708 root: openclaw-gateway (100.123.7.13:18789)

So:

#
  • don’t start another openclaw gateway
  • you already have one running on the correct IP
  • the real issue is that this running root-owned process is the one we need to inspect/manage

Next step

Run this:

ps -fp 31708
sudo -i
openclaw config get gateway.controlUi.allowedOrigins

What I want to know is:

  1. how pid 31708 was launched
#
  1. whether the root-owned running gateway really has the allowed origins you expect

Because right now, that root process is the one serving your dashboard, not the new one you keep trying to start.

Also, if you haven’t already, try opening exactly:

http://100.123.7.13:18789/

If that still says origin not allowed, then the running root process almost certainly has a different allowedOrigins config than the one you were editing.

high steeple
#

ps -fp 31708
sudo -i
openclaw config get gateway.controlUi.allowedOrigins
UID PID PPID C STIME TTY TIME CMD
root 31708 1 2 01:39 ? 00:00:14 openclaw-gateway

wicked shardBOT
#

Perfect, that explains it.

PPID 1 means that openclaw-gateway is a detached root-owned background process, not a systemd service.
That’s exactly why openclaw gateway stop keeps saying Gateway service disabled and doesn’t stop it.

So now the fix is:

  1. make sure the root config has the right allowed origins
  2. stop that exact old PID
  3. start one clean gateway

From the root shell:

openclaw config set gateway.controlUi.allowedOrigins '["http://100.123.7.13:18789","http://10.255.254.222:18789"]' --strict-json
kill 31708
#
openclaw gateway

Then open:

http://100.123.7.13:18789/

A couple important notes:

  • use plain kill, not kill -9
  • don’t launch a second gateway until that old PID is gone
  • after kill 31708, you can confirm the port is free by just starting openclaw gateway again

So yeah, the root issue was literally an old orphaned openclaw-gateway process hanging around and serving the wrong state.

high steeple
#

the web dashboard shows = control ui requires device identity (use HTTPS or localhost secure context)

wicked shardBOT
#

Yep, that’s the expected plain HTTP wall.

http://100.123.7.13:18789 is a non-secure browser context, so the Control UI can’t do the device-identity flow it wants.

So at this point, the answer is basically:

Recommended fixes

  1. Use HTTPS

    • Tailscale Serve URL (https://...ts.net) once the DNS side is working
    • or an HTTPS reverse proxy
  2. Use localhost

    • open it on the VM itself
    • or SSH tunnel it to your local machine

Important nuance

#

This will not fix remote IP access:

gateway.controlUi.allowInsecureAuth: true

That one is basically for localhost compatibility, not remote non-secure HTTP.

Break-glass option, not recommended

If you really want to use the raw IP over HTTP anyway, there is a dangerous escape hatch:

openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true --strict-json

Then restart the gateway.

#

But I would only use that as a temporary test, because it is a real security downgrade.

So, blunt version:
if you want the dashboard from another device cleanly, you really want HTTPS, not raw IP over HTTP.

Docs:

Glad that helped! šŸŽ‰
If this fixed it, please right-click the solution message → Apps → āœ… Mark Solution.
This helps Answer Overflow index the solution for future users.