decolua/9router · error · Error
Installation finished but tailscale.exe not found
Error message
Installation finished but tailscale.exe not found
What it means
installTailscaleWindows() runs the MSI installer, then polls for the tailscale.exe binary at WINDOWS_TAILSCALE_BIN for a bounded period; if the file still doesn't exist after the retries it throws 'Installation finished but tailscale.exe not found'. It means the installer exited (possibly successfully) but the expected binary never appeared at the checked path.
Source
Thrown at src/lib/tunnel/tailscale/tailscale.js:472
child.on("close", (c) => {
try { fs.unlinkSync(msiPath); } catch { /* ignore */ }
c === 0 ? resolve() : reject(new Error(`msiexec failed (code ${c})`));
});
child.on("error", reject);
});
// Verify tailscale.exe exists after install
log("Verifying installation...");
const maxWait = 10000;
const start = Date.now();
while (Date.now() - start < maxWait) {
if (fs.existsSync(WINDOWS_TAILSCALE_BIN)) {
log("Installation complete.");
return;
}
await new Promise((r) => setTimeout(r, 1000));
}
throw new Error("Installation finished but tailscale.exe not found");
}
// Self-heal: if state dir/files were previously created by root (e.g. legacy sudo daemon),
// reclaim ownership recursively so the user-mode daemon can read/write state files.
async function ensureUserOwnedDir(dir) {
try {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
return;
}
const uid = process.getuid();
const gid = process.getgid();
// Walk dir + all entries to find any non-user-owned items
const needsChown = (() => {
const stack = [dir];
while (stack.length) {
const cur = stack.pop();View on GitHub (pinned to 90b52e06ff)
Solutions
- Verify whether tailscale.exe exists elsewhere (e.g. C:\Program Files\Tailscale\) and update/align the WINDOWS_TAILScale_BIN path in src/lib/tunnel/tailscale/tailscale.js.
- Run the gateway (and therefore the installer) from an elevated (Administrator) context so the MSI can complete.
- Install Tailscale manually via the official MSI/winget (`winget install tailscale.tailscale`) and skip the in-app installer.
- Re-run the install — transient AV scan delays can exceed the 1s retry loop; a retry after completion usually finds the binary.
- Check installer logs / run the MSI manually to see the real failure (signature block, policy, disk space).
Example fix
// before
throw new Error("Installation finished but tailscale.exe not found");
// after
const candidates = [WINDOWS_TAILSCALE_BIN, "C:\\Program Files\\Tailscale\\tailscale.exe"];
const found = candidates.find((p) => fs.existsSync(p));
if (!found) throw new Error("Installation finished but tailscale.exe not found");
return found; Defensive patterns
Strategy: fallback
Validate before calling
import fs from "fs";
const BIN = "C:\\Program Files\\Tailscale\\tailscale.exe";
if (!fs.existsSync(BIN)) {
console.warn("tailscale.exe missing — installer will be (re)run");
} Type guard
const tailscaleInstalled = (p) => typeof p === "string" && fs.existsSync(p);
Try / catch
try {
await installTailscale();
} catch (e) {
if (e.message.includes("tailscale.exe not found")) {
// fallback: try winget / official MSI manually
execSync("winget install --id tailscale.tailscale -e --silent", { stdio: "inherit" });
return;
}
throw e;
} Prevention
- Run elevated (Administrator) so the MSI can complete without UAC interruption.
- Check for AV/Group Policy blocks before scripted installs on enterprise machines.
- After install failure, check alternate install paths (per-user vs per-machine) and extend the bin lookup.
- Use winget or a pre-provisioned image to install tailscale out-of-band.
When it happens
Trigger: The tailscale MSI installer failed silently, installed to a different location than the hard-coded WINDOWS_TAILSCALE_BIN path, was blocked by Windows Defender/SmartScreen or Group Policy, or installation is simply slower than the retry window (installer still finalizing). Also occurs when running in a non-elevated context where the MSI requires elevation and aborts.
Common situations: MSI requiring UAC elevation that was denied or auto-dismissed; enterprise machines with software-install restrictions; a non-standard install directory (per-user vs per-machine install); very slow disk/AV scanning delaying file appearance beyond the poll window; corrupted/partial download of the MSI.
Related errors
- Invalid sudo password
- Tailscale not installed
- MITM server.js not found at ${effectiveServerPath}. Reinstal
- install finished but package is missing — see install.log
- cancelled
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/183d13f94d28e826.
Report an issue: GitHub.