Troubleshooting

Each section is one symptom, one cause, one fix — structured so you (or the AI help desk) can jump straight to the answer.

A new spoke will not show as reachable

Symptom: you added a spoke but devf health-fleet shows it unreachable.

Check, in order:

Once all three are true, the spoke should read reachable within a poll cycle.

tailnet policy does not permit you to SSH to this node

Symptom: on a Raspberry Pi or user-owned node running Tailscale SSH, the hub's poll fails with tailnet: tailnet policy does not permit you to SSH to this node.

Cause: the node runs Tailscale SSH, which intercepts port 22 and enforces your tailnet's SSH policy. Your hub is a tagged node, so it falls outside the default "access your own devices" rule.

Do not disable Tailscale SSH on the node — if your own session to it *is* Tailscale SSH, that cuts you off. Two safe fixes:

The cockpit file tree is blank or slow

Symptom: the cockpit's file tree shows empty, or takes several seconds and sometimes fails.

Cause (managed hub): SSH relay hops without connection reuse pay a full handshake each time, and can exceed the relay timeout. On managed hubs we enable OpenSSH connection multiplexing so repeat hops reuse one channel; a blank tree usually means that multiplexing needs re-applying (for example after a hub rebuild).

Fix: on a managed hub this is our responsibility — open a support ticket and reference "SSH ControlMaster / relay timeout." The tree should return in about a second once multiplexing is warm.

The cockpit will not reconnect / I have to refresh

Symptom: after roaming networks or leaving the tab idle, the cockpit freezes and only a manual refresh recovers it.

Cause / status: this class of freeze (a half-open socket after a Wi-Fi roam or long idle) is addressed by automatic WebSocket reconnect with backoff plus a server heartbeat. If you are on a current hub build you should see it recover on its own within the backoff window.

Fix: wait through one backoff cycle; it should reconnect without a refresh. If it does not, reload once and, if it recurs, open a ticket — your hub build may need updating (see Updates). Remember: your session itself is safe on the hub (tmux-backed sessions with automatic reconnect); only the view needed to catch up.

macOS spoke: the hub cannot find tmux or dev

Symptom: a Mac spoke is on the tailnet but the hub's relay reports tmux or dev not found.

Cause: Homebrew's bin directory is not on the non-interactive SSH PATH on Apple Silicon.

Fix: surface both on a system path:

sudo ln -sf ~/.local/bin/dev /usr/local/bin/dev
sudo ln -sf "$(command -v tmux)" /usr/local/bin/tmux

Also keep the spoke's repo on the internal disk — macOS blocks non-GUI SSH sessions from files on external /Volumes/... paths.

The hub is unreachable but my work must go on

Symptom: your hub VM is down or unreachable, and you need a spoke.

Fix: a device with a local roster can bypass the hub and SSH straight to a spoke over Tailscale:

devf --direct '&<vm>' a

Your work is unaffected — it lives on the spoke — only the hub-mediated convenience layer was down.

Still stuck?

The in-cockpit AI help desk will answer most tier-1 and tier-2 questions directly from these docs. Anything it cannot resolve will escalate to a human with your transcript attached, so you never repeat yourself.

Next steps