{"record":{"id":"f06f7b4c18810a86","repo":"louislam/uptime-kuma","slug":"invalid-ping-value-must-be-between-0-and-max-pi","errorCode":null,"errorMessage":"Invalid ping value. Must be between 0 and ${MAX_PING_MS} ms.","messagePattern":"Invalid ping value\\. Must be between 0 and (.+?) ms\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/routers/api-router.js","lineNumber":59,"sourceCode":"        result.type = \"entryPage\";\n        result.entryPage = server.entryPage;\n    }\n    response.json(result);\n});\n\nrouter.all(\"/api/push/:pushToken\", async (request, response) => {\n    try {\n        let pushToken = request.params.pushToken;\n        let msg = request.query.msg || \"OK\";\n        let ping = parseFloat(request.query.ping) || null;\n        let statusString = request.query.status || \"up\";\n        const statusFromParam = statusString === \"up\" ? UP : DOWN;\n\n        // Validate ping value - max 100 billion ms (~3.17 years)\n        // Fits safely in both BIGINT and FLOAT(20,2)\n        const MAX_PING_MS = 100000000000;\n        if (ping !== null && (ping < 0 || ping > MAX_PING_MS)) {\n            throw new Error(`Invalid ping value. Must be between 0 and ${MAX_PING_MS} ms.`);\n        }\n\n        let monitor = await R.findOne(\"monitor\", \" push_token = ? AND active = 1 \", [pushToken]);\n\n        if (!monitor) {\n            throw new Error(\"Monitor not found or not active.\");\n        }\n\n        const previousHeartbeat = await Monitor.getPreviousHeartbeat(monitor.id);\n\n        let isFirstBeat = true;\n\n        let bean = R.dispense(\"heartbeat\");\n        bean.time = R.isoDateTimeMillis(dayjs.utc());\n        bean.monitor_id = monitor.id;\n        bean.ping = ping;\n        bean.msg = msg;\n        bean.downCount = previousHeartbeat?.downCount || 0;","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/routers/api-router.js#L41-L77","documentation":"Thrown by the push monitor endpoint (router.all('/api/push/:pushToken')) when the `ping` query parameter is present and falls outside [0, 100000000000] ms (0 to ~3.17 years). The bound exists so the value fits both BIGINT and FLOAT(20,2) columns. The catch block returns this as HTTP 404 with `{ok:false, msg}`.","triggerScenarios":"A push-type monitor agent calls /api/push/<token>?ping=<value> with a negative ping, or a ping larger than 100 billion ms. Commonly caused by passing the wrong unit (microseconds, nanoseconds) or a miscomputed/garbage value.","commonSituations":"Custom push script reports ping in nanoseconds or microseconds; a probe reports -1 as 'unknown'; a unit conversion bug multiplies milliseconds by 1000; a misconfigured agent emits a sentinel like -1 on failure.","solutions":["Ensure the push call sends ping in milliseconds as a non-negative number (e.g. Math.max(0, Math.round(durationMs))).","If you cannot measure ping, omit the ping query parameter entirely (parseFloat yields NaN, `|| null` makes it null, skipping the check).","Use a sentinel of omitting ping rather than -1 so the validation never trips.","Validate and clamp ping in your reporting script before the HTTP call."],"exampleFix":"// before\nfetch(`${url}/api/push/${token}?status=up&msg=OK&ping=${process.hrtime.bigint()}`) // ns, way over limit\n\n// after\nconst pingMs = Math.max(0, Math.round(durationNs / 1e6));\nfetch(`${url}/api/push/${token}?status=up&msg=OK&ping=${pingMs}`)","handlingStrategy":"validation","validationCode":"// Clamp ping to the valid range before pushing\nconst MAX_PING_MS = 100000000000;\nconst ping = (rawPing == null || isNaN(Number(rawPing))) ? null : Math.min(Math.max(0, Number(rawPing)), MAX_PING_MS);","typeGuard":"function isValidPing(ping) {\n  return ping == null || (typeof ping === 'number' && !isNaN(ping) && ping >= 0 && ping <= 100000000000);\n}","tryCatchPattern":null,"preventionTips":["Always report ping in milliseconds, not microseconds/nanoseconds.","If you cannot measure latency, omit the ping query param rather than sending -1.","Clamp negative values to 0 in the reporting script.","Unit-test the push script's ping value against the [0, 1e11] bound."],"tags":["push-monitor","validation","query-param","range-check","units"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}