louislam/uptime-kuma · error · Error

Tailscale only works if used on other machines: "${line}"

Error message

Tailscale only works if used on other machines: "${line}"

What it means

Thrown by parseTailscaleOutput() when an output line contains 'is local Tailscale IP'. Tailscale refuses to ping a node that is the current machine itself, because Tailscale is designed to connect distinct machines — pinging your own tailnet address is a configuration mistake.

Source

Thrown at server/monitor-types/tailscale-ping.js:67

     * @throws Will throw an eror if the output contains any unexpected string.
     */
    parseTailscaleOutput(tailscaleOutput, heartbeat) {
        let lines = tailscaleOutput.split("\n");

        for (let line of lines) {
            if (line.includes("pong from")) {
                heartbeat.status = UP;
                let time = line.split(" in ")[1].split(" ")[0];
                heartbeat.ping = parseInt(time);
                heartbeat.msg = "OK";
                break;
            } else if (line.includes("timed out")) {
                throw new Error(`Ping timed out: "${line}"`);
                // Immediately throws upon "timed out" message, the server is expected to re-call the check function
            } else if (line.includes("no matching peer")) {
                throw new Error(`Nonexistant or inaccessible due to ACLs: "${line}"`);
            } else if (line.includes("is local Tailscale IP")) {
                throw new Error(`Tailscale only works if used on other machines: "${line}"`);
            } else if (line !== "") {
                throw new Error(`Unexpected output: "${line}"`);
            }
        }
    }
}

module.exports = {
    TailscalePing,
};

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Replace the target with a different machine's Tailscale IP or MagicDNS name.
  2. Run 'tailscale status' to see your own IP and avoid using it as a monitor target.
  3. If you intended to check local tailscaled health, use a different monitor type (e.g. process check) rather than tailscale-ping.
Defensive patterns

Strategy: validation

Validate before calling

function isLocalIpLine(line) { return typeof line === "string" && line.includes("is local Tailscale IP"); }

Type guard

function isOwnTailnetIp(ip, status) { return status.self && (status.self.ip === ip); }

Try / catch

if (isLocalIpLine(line)) { heartbeat.status = DOWN; heartbeat.msg = "Target is the local Tailscale IP"; return; }

Prevention

When it happens

Trigger: Produced when the monitor target resolves to the Uptime-Kuma host's own Tailscale IP (100.x.x.x by default) or its own magic DNS name, so 'tailscale ping' reports 'is local Tailscale IP'.

Common situations: Operator copied the local machine's Tailscale IP into the monitor; monitor hostname resolves (via MagicDNS) to the local node; single-node test setup where source and target are the same host.

Related errors


AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12). Data as JSON: /api/errors/453f40a8d287f7ef. Report an issue: GitHub.