louislam/uptime-kuma · warning · Error
The maximum number of hours is 720
Error message
The maximum number of hours is 720
What it means
Thrown by UptimeCalculator.getData(num, type) when `type === "hour" && num > 24 * 30` (720). Bounds the amount of hourly data points returned because the calculator only retains 30 days of hourly stats (`statHourlyKeepDay = 30`). Requesting more would silently return incomplete data, so the API fails fast instead.
Source
Thrown at server/uptime-calculator.js:565
case UP:
case MAINTENANCE:
return UP;
case DOWN:
case PENDING:
return DOWN;
}
throw new Error("Invalid status");
}
/**
* @param {number} num the number of data points which are expected to be returned
* @param {"day" | "hour" | "minute"} type the type of data which is expected to be returned
* @returns {UptimeDataResult} UptimeDataResult
* @throws {Error} The maximum number of minutes greater than 1440
*/
getData(num, type = "day") {
if (type === "hour" && num > 24 * 30) {
throw new Error("The maximum number of hours is 720");
}
if (type === "minute" && num > 24 * 60) {
throw new Error("The maximum number of minutes is 1440");
}
if (type === "day" && num > 365) {
throw new Error("The maximum number of days is 365");
}
// Get the current time period key based on the type
let key = this.getKey(this.getCurrentDate(), type);
let total = {
up: 0,
down: 0,
};
let totalPing = 0;
let endTimestamp;
View on GitHub (pinned to 6b5ea01557)
Solutions
- Cap the requested duration to the supported maximum: for hours use <= 720 (30 days).
- Switch to day type for longer ranges: request "30d" / "365d" instead of "720h"+.
- If building a badge URL, pass an explicit unit (e.g. 30d) rather than a bare number.
- Validate the duration string client-side against the m/h/d/w/M/y limits before calling the API.
Example fix
// before const up = uptimeCalculator.getData(1000, "hour"); // after const hours = Math.min(num, 720); const up = uptimeCalculator.getData(hours, "hour"); // or for longer ranges: const up = uptimeCalculator.getData(Math.min(days, 365), "day");
Defensive patterns
Strategy: validation
Validate before calling
if (type === "hour") num = Math.min(num, 720);
Type guard
const withinHourLimit = (n) => typeof n === "number" && n > 0 && n <= 720;
Try / catch
try { getData(n, "hour"); } catch (e) { if (/maximum number of hours/.test(e.message)) getData(720, "hour"); else throw e; } Prevention
- Clamp hour requests to 720 at the call site.
- Prefer day type for windows over 30 days.
- Always pass an explicit unit on badge URLs.
When it happens
Trigger: Reached directly via getData(num, "hour") with num > 720, or indirectly via getDataByDuration("Nh") where N > 720 (e.g. badge URL `/api/badge/:id/status/1000` normalizes to "1000h" because a pure number is treated as hours at api-router.js:245-247). Also via weekly/monthly/yearly expansions that land on hour type — but those use day type, so not here.
Common situations: Badge URL with a large bare number interpreted as hours; custom client requesting a year of hourly uptime; scripted load test passing arbitrary period values; confusion between minutes/hours/days units in the duration string.
Related errors
- The maximum number of days is 365
- The maximum number of minutes is 1440
- Invalid duration: ${duration}
- Monitor ID is required
- Unsupported unit (${unit}) for badge duration ${duration}
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/69fa7d2406c96203.
Report an issue: GitHub.