up method
- String hostname = '',
- String? authKey,
- Uri? controlUrl,
- bool ephemeral = false,
- Duration timeout = const Duration(seconds: 30),
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— openTailscaleStatus.authUrlin 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(withTailscaleStatus.authUrlpopulated)
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();
}