Guides · September 2026

Tailscale stuck on “Starting…”

What the client is waiting for, how to find out which wait it is, and the fixes in the order that costs you the least.

What “Starting…” actually means.

The Tailscale client is a small state machine and the menu bar shows you one word of it. The daemon, tailscaled, is in one of NoState, NeedsLogin, NeedsMachineAuth, Stopped, Starting, or Running. NeedsLogin means no valid login for this machine; Running means the tunnel is up and the network map has arrived. Everything between — reaching the coordination server over HTTPS, fetching the map, bringing up the tunnel interface — happens under “Starting…”. A client that sits there is stuck on one of those steps, or the app can’t talk to tailscaled at all, which looks identical from the icon.

So ask the daemon, not the icon. tailscale status prints “Logged out.” and a login URL when the real state is NeedsLogin, “Tailscale is stopped.” for Stopped, and otherwise the state name or the peer table; --json carries it as BackendState. On the Mac App Store build the CLI lives at /Applications/Tailscale.app/Contents/MacOS/Tailscale; the Standalone build can install tailscale into /usr/local/bin from its settings.

tailscale status tailscale status --json | grep BackendState
The daemon’s own word for it

The usual causes.

Six things account for nearly every report on GitHub and the forums.

The app can’t reach tailscaled

On Windows, tailscale login answering “503 Service Unavailable: no backend” means the service runs but its state is unreadable — a power loss or a Windows update is the usual culprit (#16783). On any OS, “failed to connect to local tailscaled” means the daemon isn’t running at all.

The coordination server is unreachable

The client needs outbound TCP 443 to controlplane.tailscale.com and login.tailscale.com; the DERP relays speak HTTPS on 443 too. A captive portal, a corporate proxy, or another VPN’s kill switch — “most VPNs set aggressive firewall rules to ensure all network traffic goes through them”, in Tailscale’s words — holds the client at Starting indefinitely.

UDP is blocked

Direct connections use UDP from port 41641 and STUN on UDP 3478. Blocked UDP alone shouldn’t stop Starting, since DERP falls back over 443 — but a network that blocks UDP usually blocks more.

The node key has expired

Keys expire after 180 days by default, and then “connections to/from the given endpoint will stop working”. The fix is a re-authentication, or an admin disabling expiry for that machine in the admin console — what most people mean by the Tailscale admin panel.

Stale daemon state

tailscaled keeps its identity in /var/lib/tailscale/tailscaled.state on Linux and under C:\ProgramData\Tailscale on Windows. Corrupt it and the daemon starts, loads garbage, and never gets further; the Windows 11 25H2 upgrade leaving clients at “401 Unauthorized” (#17875) is the same family.

The platform itself

Windows needs the Wintun-based “Tailscale Tunnel” adapter; Docker Desktop, Hyper-V, and old VPN drivers can corrupt the network stack so it never appears. macOS has three builds — App Store, Standalone, and Homebrew tailscaled — and the App Store one has a known start-at-login hang that quitting and reopening clears.

The fixes, in order.

Cheapest first. Stop when the state flips to Running.

  1. 01Read the network

    tailscale netcheck prints UDP:, IPv4:, IPv6:, CaptivePortal:, Nearest DERP:, and DERP latency:. No DERP latencies at all means 443 outbound is blocked or a captive portal is in the way; UDP: false means you’ll relay — slow, not stuck. Once connected, tailscale ping <machine> says whether each reply came direct or via DERP.

    tailscale netcheck tailscale ping my-server
  2. 02Restart the daemon and read its log

    Linux below. Windows, in an administrator prompt: net stop Tailscale then net start Tailscale; logs are under C:\ProgramData\Tailscale\Logs. macOS App Store or Standalone: quit from the menu bar icon and reopen. Homebrew: sudo brew services restart tailscale. On any OS, tailscale debug daemon-logs streams the daemon’s log live.

    sudo systemctl restart tailscaled journalctl -u tailscaled --since "10 min ago"
  3. 03Re-authenticate

    tailscale logout then tailscale up gets a fresh login URL; tailscale up --force-reauth does it in one step, with Tailscale’s own warning that it “may bring down the Tailscale connection” — don’t run it over SSH to the machine you’re fixing. If the key expired while you were away, an admin can use “Temporarily extend key” on the Machines page for a 30-minute window, then “Disable key expiry” if the box is meant to live forever.

    tailscale logout tailscale up
  4. 04Clear stale state

    Stop the daemon, move its state aside, start it, and log in again. The device comes back as a new machine, so delete the old entry on the Machines page afterwards. Linux and Windows below; on macOS, uninstalling and reinstalling the app is the equivalent.

    sudo systemctl stop tailscaled sudo mv /var/lib/tailscale/tailscaled.state /var/lib/tailscale/tailscaled.state.bak sudo systemctl start tailscaled && sudo tailscale up Stop-Service Tailscale -Force Rename-Item -Path 'C:\ProgramData\Tailscale' -NewName 'Tailscale.bak' Start-Service Tailscale; tailscale up --force-reauth
    Linux, then Windows PowerShell as administrator
  5. 05Rebuild the Windows adapter

    If Network Connections shows no “Tailscale Tunnel” adapter after all of the above, the network stack itself is damaged. The recovery that works is to uninstall Tailscale, run netsh winsock reset, netsh int ip reset, and netcfg -d as administrator, reboot, and reinstall. netcfg -d wipes every adapter’s configuration, so expect to re-enter Wi-Fi passwords.

  6. 06Rule out DNS, then file it

    If the state reaches Running but names don’t resolve, the problem was never Starting: check tailscale dns status and try tailscale set --accept-dns=false. If nothing above moved the needle, tailscale bugreport --diagnose prints a marker that support or a GitHub issue can pull logs from.

    tailscale dns status tailscale bugreport --diagnose

Fix it and stay — unless the job was only ever a terminal.

A tailnet is a good answer to “my devices should share a network”, and one afternoon of Starting… doesn’t change that. If you reach a NAS’s web UI, a printer, and a handful of TCP services over it, get it Running and move on.

The structural question is narrower. If the reason you have a tailnet is to reach your own terminals — an agent grinding on a build box, a shell on the Mac mini — every step above is the cost of a network built to carry one thing. The other design skips the network: a daemon on each host that only dials out, nothing listening, no client on the device, a browser as the terminal. That’s spawnd. Sessions live on the host and survive the closed tab and the dropped connection, a new device is approved once against a short code, and your browser talks to each daemon peer-to-peer, end-to-end encrypted. Plenty of people run both — Tailscale for the network, spawnd for the terminals — and neither has to be Starting for the other to work.

Start

Reach your terminals without a tailnet at all.

$curl -fsSL https://spawnd.dev/install.sh | sh
Sign up free
Install the daemon

Questions

Why does the app say Starting… when tailscale status says Logged out?
Because the app is showing you its own guess and the CLI is showing you the daemon’s state. “Logged out.” means NeedsLogin: run tailscale up and open the URL it prints, and the icon will follow.
Will clearing tailscaled.state lose anything?
It discards the machine’s identity, so the device re-registers as a new machine and needs a fresh login. Remove the stale entry from the Machines page afterwards, and re-apply anything that was attached to the old one.
Does spawnd replace Tailscale?
No. Tailscale builds a private network; spawnd delivers terminals from hosts that dial out, with no network built at all. If you need the network, keep it. If you only needed the terminals, you can skip it — and the two run side by side without conflict.