louislam/uptime-kuma · error · Error

Database connection/query failed: ${error.message}

Error message

Database connection/query failed: ${error.message}

What it means

Catch-all wrapper in MssqlMonitorType.check: any error whose message does NOT contain 'did not meet the specified conditions' is re-thrown as 'Database connection/query failed: <original>'. This captures connection failures, auth failures, timeouts, TLS errors, and SQL syntax errors. Condition-evaluation errors are intentionally re-thrown unchanged so they surface verbatim.

Source

Thrown at server/monitor-types/mssql.js:57

                    throw new Error(`Query result did not meet the specified conditions (${result})`);
                }

                heartbeat.status = UP;
                heartbeat.msg = "Query did meet specified conditions";
            } else {
                // Backwards compatible: just check connection and return row count
                const result = await this.mssqlQuery(monitor.databaseConnectionString, query);
                heartbeat.ping = dayjs().valueOf() - startTime;
                heartbeat.status = UP;
                heartbeat.msg = result;
            }
        } catch (error) {
            heartbeat.ping = dayjs().valueOf() - startTime;
            // Re-throw condition errors as-is, wrap database errors
            if (error.message.includes("did not meet the specified conditions")) {
                throw error;
            }
            throw new Error(`Database connection/query failed: ${error.message}`);
        }
    }

    /**
     * Run a query on MSSQL server (backwards compatible - returns row count)
     * @param {string} connectionString The database connection string
     * @param {string} query The query to validate the database with
     * @returns {Promise<string>} Row count message
     */
    async mssqlQuery(connectionString, query) {
        let pool;
        try {
            pool = new mssql.ConnectionPool(connectionString);
            await pool.connect();
            const result = await pool.request().query(query);

            if (result.recordset) {
                return "Rows: " + result.recordset.length;

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Test the identical connection string with sqlcmd or Azure Data Studio from the Uptime Kuma host to isolate network vs auth vs query.
  2. Confirm port 1433 (or named-instance port) is reachable and SQL Browser (UDP 1434) is allowed if using a named instance.
  3. Verify credentials and that 'SQL Server Authentication' / the AD identity is enabled; check the SQL errorlog for the failed login.
  4. If TLS/encrypt is required, supply the right options in the connection string (e.g. encrypt=true, trustServerCertificate as appropriate).
  5. Run the query standalone to catch syntax/permission errors before relying on the monitor.

Example fix

// before: Server=10.0.0.5,1433;Database=app;User Id=u;Password=p;   (encrypt required by server)
// after:  Server=10.0.0.5,1433;Database=app;User Id=u;Password=p;Encrypt=true;TrustServerCertificate=true;
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight reachability check before relying on the monitor:
const net = require('net');
function portOpen(host, port, ms=2000) {
  return new Promise(res => { const s = new net.Socket(); s.setTimeout(ms);
    s.on('connect', () => { s.destroy(); res(true); });
    s.on('timeout', () => { s.destroy(); res(false); });
    s.on('error', () => res(false));
    s.connect(port, host); });
}

Try / catch

async function withRetry(fn, retries=3, backoffMs=1000) {
  for (let i=0; i<=retries; i++) { try { return await fn(); } catch (e) {
    if (/Database connection\/query failed/.test(e.message) && i<retries) await new Promise(r=>setTimeout(r, backoffMs*2**i)); else throw e; } }
}

Prevention

When it happens

Trigger: new mssql.ConnectionPool(connectionString).connect() rejects (network unreachable, login failed, timeout), pool.request().query(query) rejects (syntax error, permission denied, object not found), or the single-value helpers throw 'Query returned no results'/'Multiple values...'. The substring guard then forwards everything except condition failures.

Common situations: Wrong connection string format (Server=name vs full data-source syntax); SQL Server Browser/port 1433 blocked by firewall; encrypted (TLS) connection required but not negotiated; SQL login disabled / wrong credentials; query references a table in the wrong database/schema; mssql npm driver version mismatch with server.

Related errors


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