louislam/uptime-kuma · error · Error
Error in output: ${res.stderr.toString()}
Error message
Error in output: ${res.stderr.toString()} What it means
Thrown by runTailscalePing() after the spawn of 'tailscale ping' completed (did not throw) but wrote to stderr and exited with a non-zero code. promisify-child-process resolves the spawn with {stdout, stderr, code}; this branch converts a failed exit into an explicit error using the stderr text.
Source
Thrown at server/monitor-types/tailscale-ping.js:35
throw new Error(`Error checking Tailscale ping: ${err}`);
}
}
/**
* Runs the Tailscale ping command to the given URL.
* @param {string} hostname The hostname to ping.
* @param {number} interval Interval to send ping
* @returns {Promise<string>} A Promise that resolves to the output of the Tailscale ping command
* @throws Will throw an error if the command execution encounters any error.
*/
async runTailscalePing(hostname, interval) {
let timeout = interval * 1000 * 0.8;
let res = await childProcessAsync.spawn("tailscale", ["ping", "--c", "1", hostname], {
timeout: timeout,
encoding: "utf8",
});
if (res.stderr && res.stderr.toString() && res.code !== 0) {
throw new Error(`Error in output: ${res.stderr.toString()}`);
}
if (res.stdout && res.stdout.toString()) {
return res.stdout.toString();
} else {
throw new Error("No output from Tailscale ping");
}
}
/**
* Parses the output of the Tailscale ping command to update the heartbeat.
* @param {string} tailscaleOutput The output of the Tailscale ping command.
* @param {object} heartbeat The heartbeat object to update.
* @returns {void}
* @throws Will throw an eror if the output contains any unexpected string.
*/
parseTailscaleOutput(tailscaleOutput, heartbeat) {
let lines = tailscaleOutput.split("\n");
View on GitHub (pinned to 6b5ea01557)
Solutions
- Run 'tailscale ping --c 1 <hostname>' manually as the Uptime-Kuma user to reproduce and read the stderr message.
- Ensure tailscaled is running and the host is logged in ('tailscale status' should list peers).
- Confirm the tailscale CLI version supports the flags used; upgrade or adjust the invocation if '--c' is not accepted.
- If running in containers, make sure the tailscale socket/daemon is reachable from the Uptime-Kuma container.
Defensive patterns
Strategy: try-catch
Validate before calling
function isNonZeroExit(res) { return res && res.code !== 0 && res.stderr && res.stderr.toString().trim().length > 0; } Type guard
function hasStderr(res) { return !!res?.stderr && res.stderr.toString().trim().length > 0; } Try / catch
if (isNonZeroExit(res)) { heartbeat.status = DOWN; heartbeat.msg = res.stderr.toString().trim(); return; } Prevention
- Run 'tailscale status' before relying on tailscale-ping monitors.
- Keep the tailscale CLI version compatible with the flags used.
- Ensure the Uptime-Kuma user can invoke tailscale.
When it happens
Trigger: Produced when 'tailscale ping --c 1 <hostname>' exits non-zero and prints to stderr: not logged in, tailscaled unreachable, permission denied, unknown flag, or a tailscale daemon error.
Common situations: tailscale daemon not running; the Uptime-Kuma process user cannot invoke tailscale; tailscale version that does not support '--c' syntax; auth expired; node offline in the tailnet; running inside a container without tailscaled sidecar.
Related errors
- Error checking Tailscale ping: ${err}
- No output from Tailscale ping
- Ping timed out: "${line}"
- Nonexistant or inaccessible due to ACLs: "${line}"
- Tailscale only works if used on other machines: "${line}"
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/f1a1fd13c0c6bba5.
Report an issue: GitHub.