louislam/uptime-kuma · error · Error

Error in output: ${stderr.toString()}

Error message

Error in output: ${stderr.toString()}

What it means

runSipSak shells out to the `sipsak` binary with -s sip:host:port, --from, and -v. If the child produced no stdout but did produce stderr, the monitor treats stderr as a hard failure and throws it prefixed with 'Error in output:'. This surfaces sipsak's own diagnostics instead of silently succeeding.

Source

Thrown at server/monitor-types/sip-options.js:38

    }

    /**
     * Runs Sipsak options ping
     * @param {string} hostname SIP server address to send options.
     * @param {number} port SIP server port
     * @param {number} timeout timeout of options reply
     * @returns {Promise<string>} A Promise that resolves to the output of the Sipsak options ping
     * @throws Will throw an error if the command execution encounters any error.
     */
    async runSipSak(hostname, port, timeout) {
        const { stdout, stderr } = await execFile(
            "sipsak",
            ["-s", `sip:${hostname}:${port}`, "--from", `sip:sipsak@${hostname}`, "-v"],
            { timeout }
        );

        if (!stdout && stderr && stderr.toString()) {
            throw new Error(`Error in output: ${stderr.toString()}`);
        }
        if (stdout && stdout.toString()) {
            return stdout.toString();
        } else {
            throw new Error("No output from sipsak");
        }
    }

    /**
     * @param {string} res response to be parsed
     * @param {object} heartbeat heartbeat object to update
     * @returns {void} returns nothing
     */
    parseSipsakResponse(res, heartbeat) {
        let lines = res.split("\n");
        for (let line of lines) {
            if (line.includes("200 OK")) {
                heartbeat.status = UP;

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Run sipsak manually with the same arguments to read the stderr: sipsak -s sip:host:port --from sip:sipsak@host -v.
  2. Confirm the host/port is a reachable SIP server.
  3. Install/build sipsak with TLS support if targeting sips: URIs.
  4. Check firewall rules for the SIP signalling port (UDP/TCP 5060, 5061).

Example fix

# before
Error in output: target 'sip:bad.host:5060' unknown
# after
# correct the hostname/port in the monitor
Defensive patterns

Strategy: validation

Validate before calling

const { execFile } = require('child_process');
const util = require('util');
const execFileP = util.promisify(execFile);
async function preflightSipsak(host, port) {
  try {
    await execFileP('sipsak', ['-V']); // version probe; fails if binary missing
  } catch {
    throw new Error('sipsak binary not installed');
  }
}

Type guard

function hasSipsakStderr(out) { return !!out && !out.stdout && !!out.stderr; }

Try / catch

try {
  await runSipSak(hostname, port, timeout);
} catch (e) {
  if (/^Error in output:/.test(e.message)) {
    // surface sipsak stderr verbatim for diagnosis
  }
  throw e;
}

Prevention

When it happens

Trigger: execFile resolves but stdout is empty and stderr is non-empty: sipsak emitted an error/warning to stderr (e.g. 'target host unknown', TLS errors, or malformed SIP URI). The branch at sip-options.js:38 fires.

Common situations: Wrong port, target not a SIP server, DNS issues, sipsak built without TLS for a sips: target, or firewall dropping SIP packets such that sipsak errors out.

Related errors


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