louislam/uptime-kuma · error · Error

${error.message}

Error message

${error.message}

What it means

The final else branch in checkSingleNode's catch handles errors with no axios `.response` property — i.e. the request never got an HTTP answer. It throws a fresh Error wrapping error.message. This is the network/transport failure path, distinct from the 503 and generic-status branches above it.

Source

Thrown at server/monitor-types/rabbitmq.js:106

                `[${monitor.name}] Axios Response: status=${res.status} body=${JSON.stringify(res.data)}`
            );

            if (res.status === 200) {
                log.debug("monitor", `[${monitor.name}] Node ${nodeInfo} is healthy`);
                // Success - return without error
            } else if (res.status === 503) {
                throw new Error(res.data.reason);
            } else {
                throw new Error(`${res.status} - ${res.statusText}`);
            }
        } catch (error) {
            if (axios.isCancel(error)) {
                throw new Error("Request timed out");
            } else if (error.response) {
                // Re-throw with the original error message if it's already formatted
                throw error;
            } else {
                throw new Error(error.message);
            }
        }
    }
}

module.exports = {
    RabbitMqMonitorType,
};

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Verify host and port resolve and accept connections: nc -vz host 15672.
  2. Check DNS resolution and /etc/hosts or the cluster's name resolution.
  3. If TLS: confirm the certificate is trusted or adjust the relevant TLS settings.
  4. Ensure the RabbitMQ management plugin is listening (netstat -tlnp | grep 15672).

Example fix

# before
getaddrinfo ENOTFOUND rabbit-prod.local
# after
# add DNS/hosts entry or correct the node hostname in the monitor
Defensive patterns

Strategy: validation

Validate before calling

const dns = require('dns').promises;
const net = require('net');
async function preflightRabbitReachability(baseUrl) {
  const u = new URL(baseUrl);
  await dns.lookup(u.hostname);
  const ok = await new Promise(res => {
    const s = net.connect({ host: u.hostname, port: Number(u.port || 15672) });
    s.setTimeout(3000, () => { s.destroy(); res(false); });
    s.once('connect', () => { s.destroy(); res(true); });
    s.once('error', () => res(false));
  });
  if (!ok) throw new Error(`Cannot reach ${u.hostname}:${u.port || 15672}`);
}

Type guard

function isTransportError(e) { return !e.response && (e.code === 'ECONNREFUSED' || e.code === 'ENOTFOUND' || e.code === 'ECONNRESET'); }

Try / catch

try {
  await checkSingleNode(monitor, baseUrl, nodeInfo);
} catch (e) {
  if (/ENOTFOUND|ECONNREFUSED|ECONNRESET/.test(e.message)) {
    log.error('Network/DNS issue reaching RabbitMQ node');
  }
  throw e;
}

Prevention

When it happens

Trigger: axios fails before receiving a response: ECONNREFUSED, ENOTFOUND (DNS), ECONNRESET, EAI_AGAIN, certificate errors, or socket hangup. Since error.response is undefined, the catch falls to else and re-wraps the OS/axios message.

Common situations: Wrong host/port, DNS not resolving the node name, firewall dropping the connection, TLS certificate mismatch with rejectUnauthorized, or the RabbitMQ node process not listening on the management port.

Related errors


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