decolua/9router · error · Error
Tailscale not installed
Error message
Tailscale not installed
What it means
startFunnel(port) needs the tailscale CLI binary and resolves it via getTailscaleBin(); when the binary can't be found on the system it throws 'Tailscale not installed'. The tunnel layer refuses to attempt `tailscale funnel` without the executable, so the failure is immediate and deterministic.
Source
Thrown at src/lib/tunnel/tailscale/tailscale.js:743
return;
}
// Only resolve alreadyLoggedIn if status confirms BackendState=Running
if (isTailscaleLoggedIn()) {
resolved = true;
clearTimeout(timeout);
clearInterval(statusPoll);
resolve({ alreadyLoggedIn: true });
return;
}
// Otherwise keep polling — daemon may publish AuthURL shortly after exit
});
});
}
/** Start tailscale funnel for the given port */
export async function startFunnel(port) {
const bin = getTailscaleBin();
if (!bin) throw new Error("Tailscale not installed");
// Reset any existing funnel
try { execSync(`"${bin}" ${SOCKET_FLAG.join(" ")} funnel --bg reset`, { stdio: "ignore", windowsHide: true }); } catch (e) { /* ignore */ }
return new Promise((resolve, reject) => {
const child = spawn(bin, tsArgs("funnel", "--bg", `${port}`), {
stdio: ["ignore", "pipe", "pipe"],
windowsHide: true
});
let resolved = false;
let output = "";
const timeout = setTimeout(() => {
if (resolved) return;
resolved = true;
// --bg exits after setup, read actual hostname from status
const url = getActualFunnelUrl() || getTailscaleFunnelUrl(port);View on GitHub (pinned to 90b52e06ff)
Solutions
- Install tailscale (official installer, `winget install tailscale.tailscale`, brew, or the Linux install script) before enabling the funnel.
- Confirm `tailscale version` works in the same shell/environment the gateway runs in; if not, fix PATH (e.g. symlink into /usr/local/bin).
- Check what getTailscaleBin() searches and point the environment (PATH) at your actual install location.
- Restart the gateway process after installing tailscale so binary discovery re-runs.
- Use the built-in install flow (installTailscale) instead of expecting a pre-installed binary.
Example fix
// before
await startFunnel(20128);
// after
import { getTailscaleBin } from ".../tailscale.js";
if (!getTailscaleBin()) {
await installTailscale(); // or instruct user to install tailscale
}
await startFunnel(20128); Defensive patterns
Strategy: fallback
Validate before calling
import { execSync } from "child_process";
function tailscaleAvailable() {
try { execSync("tailscale version", { stdio: "ignore" }); return true; }
catch { return false; }
}
if (!tailscaleAvailable()) console.warn("tailscale missing — install before enabling funnel"); Type guard
const hasTailscale = (bin) => typeof bin === "string" && bin.length > 0;
Try / catch
try {
await startFunnel(port);
} catch (e) {
if (e.message === "Tailscale not installed") {
await installTailscale(); // fallback: auto-install
return startFunnel(port);
}
throw e;
} Prevention
- Check getTailscaleBin() at startup and show an install prompt if null.
- Ensure the gateway's daemon environment has tailscale on PATH (systemd services have minimal PATH).
- Restart the gateway after installing tailscale so binary discovery refreshes.
- Provision tailscale in Docker images / AMIs used to run the gateway.
When it happens
Trigger: Calling startFunnel (or the enableTailscale flow that reaches it) on a machine where tailscale was never installed, was uninstalled, is installed but not on PATH, or where the platform-specific bin lookup (getTailscaleBin) checks a location that doesn't match the actual install (e.g. per-user vs per-machine Windows install, Homebrew vs /usr/local on macOS).
Common situations: Fresh machine or container without tailscale; PATH missing the tailscale dir in the server's environment (systemd/daemon environments often have a minimal PATH); tailscale installed after the gateway process started with a cached lookup; Windows install to a non-default directory.
Related errors
- Invalid sudo password
- Installation finished but tailscale.exe not found
- Unsupported platform: ${platform}
- cancelled
- Health check timeout after ${HEALTH_CHECK.timeoutMs}ms
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/6d248258756b4dc1.
Report an issue: GitHub.