up method

  1. @override
Future<TailscaleStatus> up({
  1. String hostname = '',
  2. String? authKey,
  3. Uri? controlUrl,
  4. bool ephemeral = false,
  5. Duration timeout = const Duration(seconds: 30),
})
override

Brings the embedded Tailscale node up and connects to the control plane — Tailscale's coordination service at controlplane.tailscale.com, or a self-hosted Headscale if you set controlUrl. Registers the node on first launch, reconnects from persisted credentials on subsequent launches.

authKey is required for first registration; get one from the tailnet admin panel at login.tailscale.com/admin/settings/keys (see tailscale.com/kb/1085/auth-keys). Reusable keys let you call up from multiple processes. Subsequent launches can omit it — the persisted session state reconnects automatically.

Set ephemeral to register this process as a short-lived node. Ephemeral nodes are removed from the tailnet automatically after they go inactive by control-plane cleanup. Calling logout stops the local node and clears local credentials, but tailnet removal still follows the control plane's ephemeral-node cleanup behavior. Use this for CI jobs, preview environments, disposable tests, and other nodes whose identity should not outlive the process. This affects registration with the control plane; use a fresh or cleared stateDir passed to Tailscale.init when you need to force a new ephemeral identity.

hostname sets the tailnet-visible hostname and the MagicDNS label, so the node becomes reachable at <hostname>.<tailnet>.ts.net. Leave unset to let the embedded runtime pick the OS default.

Resolves on the first stable state: running, needsLogin, or needsMachineAuth. This intentionally differs from Go's tsnet.Server.Up, which blocks only on running — a Dart app that needs to drive an in-app auth flow should not have to re-enter up just to see the TailscaleStatus.authUrl. Inspect the returned TailscaleStatus.state to decide what to do next:

  • running — ready; http, tcp, etc. are usable.
  • needsLogin — open TailscaleStatus.authUrl in a browser / web view; the node finishes connecting after the user completes the flow.
  • needsMachineAuth — authenticated but awaiting admin approval on the control plane ( device approval).

Transitions delivered via onStateChange:

  • First launch: noState → starting → running
  • Reconnect with persisted creds: stopped → starting → running
  • If creds are expired: stopped → starting → needsLogin (with TailscaleStatus.authUrl populated)

No-op if already running (without a new authKey).

timeout bounds how long up waits for the node to reach a stable state after the native runtime starts. Increase it for slow mobile networks or self-hosted control planes.

Throws TailscaleUpException if no authKey is provided and no persisted session state exists, or if the node fails to reach a stable state before timeout (e.g. control plane unreachable).

Implementation

@override
Future<TailscaleStatus> up({
  String hostname = '',
  String? authKey,
  Uri? controlUrl,
  bool ephemeral = false,
  Duration timeout = const Duration(seconds: 30),
}) async {
  final upError = _upError;
  if (upError != null) {
    throw upError;
  }

  _started = true;
  _stateController.add(NodeState.starting);
  _running = true;
  Future.microtask(() => _stateController.add(NodeState.running));
  _emitPeers();
  return status();
}