louislam/uptime-kuma · error · Error

TLS certificate is not authorized: ${tlsInfo.error}

Error message

TLS certificate is not authorized: ${tlsInfo.error}

What it means

Thrown by handleTLSInfo for an HTTPS monitor when ignoreTls is false and the probe-reported tlsInfo.authorized is false. The specific TLS error (expired, self-signed, hostname mismatch, untrusted CA) from tlsInfo.error is included. handleTLSInfo is only called when no keyword/jsonQuery short-circuited the HTTP check.

Source

Thrown at server/monitor-types/globalping.js:454

        );
        heartbeat.status = UP;
    }

    /**
     * Updates the TLS information for a monitor.
     * @param {object} monitor - The monitor object.
     * @param {string} protocol - The protocol used for the monitor.
     * @param {object} probe - The probe object containing location information.
     * @param {object} tlsInfo - The TLS information object.
     * @returns {Promise<void>}
     */
    async handleTLSInfo(monitor, protocol, probe, tlsInfo) {
        if (!tlsInfo) {
            return;
        }

        if (!monitor.ignoreTls && protocol === "HTTPS" && !tlsInfo.authorized) {
            throw new Error(this.formatResponse(probe, `TLS certificate is not authorized: ${tlsInfo.error}`));
        }

        let tlsInfoBean = await R.findOne("monitor_tls_info", "monitor_id = ?", [monitor.id]);

        if (tlsInfoBean == null) {
            tlsInfoBean = R.dispense("monitor_tls_info");
            tlsInfoBean.monitor_id = monitor.id;
        } else {
            try {
                let oldCertInfo = JSON.parse(tlsInfoBean.info_json);

                if (
                    oldCertInfo &&
                    oldCertInfo.certInfo &&
                    oldCertInfo.certInfo.fingerprint256 !== tlsInfo.fingerprint256
                ) {
                    log.debug("monitor", "Resetting sent_history");
                    await R.exec(

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Renew/replace the certificate if it is expired or malformed
  2. Fix hostname mismatches by serving the cert for the correct CN/SAN
  3. Install the full intermediate chain on the server
  4. If the self-signed/untrusted cert is intentional, enable 'Ignore TLS/Error' (ignoreTls) on the monitor

Example fix

// before: self-signed cert breaks HTTPS monitor, ignoreTls off
monitor.ignoreTls = false;
// after: accept the cert you control
monitor.ignoreTls = true; // or fix the cert chain
Defensive patterns

Strategy: validation

Validate before calling

// Nothing to validate at runtime for the remote cert, but you can decide policy:
// If the cert is intentionally untrusted, set ignoreTls.
if (monitor.ignoreTls) {
    log.debug("monitor", "TLS errors will be ignored for this monitor");
}

Try / catch

if (!monitor.ignoreTls && protocol === "HTTPS" && !tlsInfo.authorized) {
    throw new Error(this.formatResponse(probe, `TLS certificate is not authorized: ${tlsInfo.error}`));
}

Prevention

When it happens

Trigger: protocol === 'HTTPS', monitor.ignoreTls is false, and result.tls.authorized === false. The certificate failed Node's verification: EXPIRED, self-signed (UNABLE_TO_VERIFY_LEAF_SIGNATURE), hostname mismatch (ERR_CERT_COMMON_NAME_INVALID), or an untrusted chain.

Common situations: Certificate expired and not renewed, self-signed certificate used in staging/internal hosts, certificate issued for a different hostname, or an incomplete intermediate chain.

Understand the failure class

Related errors


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