#Unable to connect Mac node to remote gateway

1 messages · Page 1 of 1 (latest)

shut parrot
#

I'm trying to connect to my remote gateway as a node on my mac, through the macos menu bar companion app. Tailscale was configured independently. I am able to ssh into the vps through ssh.

Details:
Remote gateway
$ openclaw --version
2026.3.2

Local:
$openclaw status
Dashboard: http://127.0.0.1:18789/
OS: macos 26.3 (arm64) · node 25.6.1
Tailscale: off
Channel: stable (default)
Update: pnpm · npm latest 2026.3.2
Gateway: remote · wss://100.94.254.65:18789 (config gateway.remote.url) · unreachable (connect failed: connect ECONNREFUSED 100.94.254.65:18789)
Gateway service: LaunchAgent installed · not loaded · unknown
Node service: LaunchAgent not installed
Agents: 1 · no bootstrap files · sessions 2 · default main active 23h ago
...

  • Tailscale set up independently, but tailscale automation not enabled.
  • Hostinger firewall accepts udp from 41641
  • No pending devices to approve on remote.
  • Removing optional port on ssh string on macos app stuck on testing (maybe because the key is passphrase protected?)
tawdry novaBOT
#

connect ECONNREFUSED 100.94.254.65:18789 is the key clue: your Mac can reach that IP, but nothing is listening on port 18789 on that interface (most commonly: the gateway is bound to 127.0.0.1 on the VPS, so connecting to the Tailscale IP will always be refused).

Two clean ways to fix it (pick one):

Option A (recommended): keep gateway bound to loopback, use Tailscale Serve (wss/https)

On the VPS, enable Serve:

Then on the Mac, set the remote URL to the Serve URL (typically wss://<magicdns>/), not wss://100.x.x.x:18789.

Why: wss://100.x:18789 implies TLS directly on 18789, which you don’t have unless you’re using Serve/Funnel or a reverse proxy.

Option B: bind the gateway directly to the tailnet IP (plain ws://)

On the VPS, set:

#
  • gateway.bind: "tailnet" (and make sure auth is set, e.g. token mode)
  • then connect with ws://100.94.254.65:18789 (not wss://...)

Docs: https://docs.openclaw.ai/help/faq (see “Tailnet-only (bind to Tailnet IP)” and remote gateways/nodes sections)


If you’re using the macOS menubar app “Remote over SSH”

This is a separate gotcha: the app uses non-interactive SSH (BatchMode), so if your SSH key is passphrase-protected and not already loaded into ssh-agent / Keychain, “Test remote” will look like it’s hanging/failing.

Docs: https://docs.openclaw.ai/platforms/mac/remote

So either:

  • load the key into ssh-agent/Keychain first, then retry “Test remote”, or
  • use a key that doesn’t require an interactive passphrase prompt (less ideal).

#

What I’d like you to paste (to confirm in one round-trip)

On the VPS:

openclaw gateway status

That output includes the “Listening:” line, which will immediately confirm whether it’s bound to loopback vs tailnet, and whether it’s actually up.

Once the gateway is reachable, your Mac node should start showing a pending device request on the VPS (openclaw devices list), and then you can approve it.

shut parrot
#

User@srv1468171:~$ openclaw gateway --tailscale serve

🦞 OpenClaw 2026.3.2 (85377a2) — Type the command with confidence—nature will provide the stack trace if needed.
05:09:30 [canvas] host mounted at http://127.0.0.1:18789/__openclaw__/canvas/ (root /home/User/.openclaw/canvas)
05:09:30 [heartbeat] started
05:09:30 [health-monitor] started (interval: 300s, startup-grace: 60s, channel-connect-grace: 120s)
05:09:30 [gateway] agent model: github-copilot/gpt-5-mini
05:09:30 [gateway] listening on ws://127.0.0.1:18789, ws://[::1]:18789 (PID 21999)
05:09:30 [gateway] log file: /tmp/openclaw/openclaw-2026-03-08.log
05:09:45 [tailscale] serve failed: Command failed: /usr/bin/tailscale serve --bg --yes 18789

User@srv1468171:~$ openclaw gateway status

Service: systemd (enabled)
File logs: /tmp/openclaw/openclaw-2026-03-08.log
Command: /usr/bin/node /home/User/.npm-global/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: stopped (state inactive, sub dead, last exit 0, reason 1)
RPC probe: ok

Service is loaded but not running (likely exited immediately).
File logs: /tmp/openclaw/openclaw-2026-03-08.log
Logs: journalctl --user -u openclaw-gateway.service -n 200 --no-pager

Troubles: run openclaw status
Troubleshooting: https://docs.openclaw.ai/troubleshooting

tawdry novaBOT
#

Nice, this output basically pins it down:

  • Your VPS gateway is bind=loopback (127.0.0.1), and it even says: “Loopback-only gateway; only local clients can connect.”
  • So your Mac trying wss://100.94.254.65:18789 will always fail (nothing is listening on 100.94…:18789).

Now you have 3 workable paths:

1) Easiest: macOS app “Remote over SSH” (SSH tunnel)

If you use the menubar app’s SSH tunnel transport, the gateway can stay loopback-only and you don’t need any Tailscale Serve at all.

Two gotchas you already suspected:

  • If your VPS SSH is on a non-22 port, you must keep user@host:port in the app.
  • The app uses BatchMode / non-interactive ssh, so a passphrase-protected key will fail unless it’s already unlocked via ssh-agent / Keychain.

Docs: https://docs.openclaw.ai/platforms/mac/remote

2) Use Tailscale Serve (wss/https) — your attempt failed, we need the real tailscale error

#

openclaw gateway --tailscale serve failed because the underlying command failed:

/usr/bin/tailscale serve --bg --yes 18789

Run this on the VPS and paste the exact error (this will tell us if it’s permissions vs not logged in vs HTTPS not enabled):

tailscale status
tailscale serve --bg --yes 18789

Very common case: tailscale commands require sudo / operator permissions. If the error says “Access denied … use sudo …” then you either:

  • run Serve with sudo ..., or
  • configure Tailscale so your user is allowed to run tailscale serve (Tailscale “operator” setting).

Docs for the OpenClaw side: https://docs.openclaw.ai/gateway/tailscale

#

3) Bind gateway directly to tailnet IP (no Serve; plain ws)

If you don’t want to fight Serve right now, switch the VPS gateway to:

  • gateway.bind: "tailnet"
  • then connect from the Mac using ws://100.94.254.65:18789 (note: ws, not wss)

This is also documented in the Tailscale page under “Tailnet-only (bind to Tailnet IP)”.


One more thing: your openclaw gateway status says the systemd service is not running, even though RPC probe: ok (so something is/was listening). Once we pick one of the options above, restart cleanly with:

openclaw gateway restart

If you paste the output of the two tailscale … commands above, I can tell you exactly why Serve is failing on that VPS.

shut parrot
#

I'd prefer 1, ssh is on port 22. Stuck on connecting. How do I do that "unlocked via ssh-agent / Keychain" thing?

tawdry novaBOT
#

Because the macOS app uses non-interactive SSH (BatchMode), it cannot pop up a passphrase prompt. So you need to make sure your key is already unlocked in the ssh-agent (and ideally stored in Keychain so it stays unlocked).

Here’s the usual macOS way:

1) Figure out which key SSH is using

From your Mac:

ssh -v user@srv1468171 'echo ok'

In the debug output, look for lines like Offering public key: ... to see which ~/.ssh/... key file it’s trying.

2) Add that key to the agent + Keychain

Most modern macOS versions:

#
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
# or whatever key file you actually use

If that flag isn’t supported on your system, try the older macOS variant:

ssh-add -K ~/.ssh/id_ed25519

Then confirm it’s loaded:

ssh-add -l
#

3) Make sure non-interactive SSH works (this matches the app)

This is the exact kind of check the app is effectively doing:

ssh -o BatchMode=yes user@srv1468171 'echo ok'
  • If this prints ok, your key is unlocked and the app should be able to connect.
  • If it fails with something like Permission denied (publickey) or it tries password auth, the app will be stuck.

4) (Recommended) Put it in ~/.ssh/config so it’s stable

Edit ~/.ssh/config:

Host openclaw-vps
  HostName srv1468171
#
  User youruser
  Port 22
  IdentityFile ~/.ssh/id_ed25519
  AddKeysToAgent yes
  UseKeychain yes

Then test:

ssh -o BatchMode=yes openclaw-vps 'echo ok'

And in the macOS app, use youruser@openclaw-vps (or youruser@srv1468171) as the SSH target.


#

If you run ssh -o BatchMode=yes user@srv1468171 'echo ok' and paste the exact error text, I can tell you whether you’re hitting (a) key not loaded, (b) wrong key, (c) server not accepting that key, or (d) host key / known_hosts issues.

shut parrot
#

$ ssh -o BatchMode=yes 100.94.254.65 'echo ok'
ok
Mac os app still stuck on testing/ connecting
target: user@100.94.254.65

tawdry novaBOT
#

Good: ssh -o BatchMode=yes 100.94.254.65 'echo ok' returning ok means the key/passphrase part is solved (at least for some ssh target).

Now the macOS app’s Test remote does more than echo ok — it tries to run openclaw … remotely and usually also sets up a port-forward. So we need to check the two most common remaining causes:

A) Make sure you can run openclaw over SSH non-interactively (same user as the app)

Please run this from your Mac with the exact same target string you entered in the app:

ssh -o BatchMode=yes user@100.94.254.65 'command -v openclaw && openclaw --version && openclaw status --json | head -c 200'

What we learn:

  • If command -v openclaw prints nothing / you get openclaw: command not found (exit 127), the app will be stuck too.
    • Fix is: put openclaw on a PATH that non-interactive SSH sessions see (docs call this out explicitly): https://docs.openclaw.ai/platforms/mac/remote
    • Practical fix on the VPS is usually to symlink the real binary into /usr/local/bin/openclaw (so it’s always found), or set the app’s CLI path to the full path.

B) Local port-forward collision (port 18789 already in use on the Mac)

#

On your Mac:

lsof -iTCP:18789 -sTCP:LISTEN

If something is already listening on 18789, the app’s SSH tunnel can’t bind the local port and “Test remote” can hang/fail.

Quick sanity check: does SSH tunnel work manually?

From your Mac:

ssh -N -L 18789:127.0.0.1:18789 user@100.94.254.65

Then open http://127.0.0.1:18789/ in a browser on the Mac. If that works, the app should work too (and we can focus on “how the app is invoking openclaw / which user / which port”).

#

If you paste the output of the A command (even just whether it finds openclaw + the first ~10 lines), we can zero in immediately.

shut parrot
#

Progress after the symlink, now getting this error msg from the mac app when testing connection:
gateway error: gateway connect: connect to gateway @ ws://127.0.0.1:18789: unauthorized: gateway token mismatch (provide gateway auth token)

tawdry novaBOT
#

Perfect — that means the SSH tunnel + remote CLI path are working now. You’re just hitting Gateway auth.

Even over an SSH tunnel, the gateway still expects the same token as gateway.auth.token on the VPS. Your Mac app is either sending no token, or an old/wrong one.

1) Get the gateway token from the VPS (don’t paste it here)

On the VPS:

openclaw config get gateway.auth.token

If it’s empty/missing, generate one:

openclaw doctor --generate-gateway-token
openclaw config get gateway.auth.token
#

2) Put that token into the macOS app (Remote over SSH setup)

In the macOS app settings for the remote gateway connection, enter that value in the field that’s usually labeled Gateway Token / Auth token (not the SSH key/passphrase).

If you don’t see a token field in the SSH settings, another reliable way to confirm you have the right token is:

  • keep your tunnel active
  • open http://127.0.0.1:18789/ on the Mac
  • in the Control UI, paste the token in Gateway Access and connect

(If the browser connects with that token, the app will too — it’s the same gateway auth.)

3) If you previously rotated tokens

Make sure you didn’t accidentally set a different token on the Mac side (e.g. in gateway.remote.token) that no longer matches the VPS. The rule is:

  • VPS: gateway.auth.token = source of truth
  • Clients (mac app / Control UI / remote CLI): must use that exact token

If you tell me whether openclaw config get gateway.auth.token returns a value (yes/no — not the token itself), I can point you to the exact next click/setting depending on which UI path you’re using in the app.