louislam/uptime-kuma · error · Error
Invalid timezone:${timezone}
Error message
Invalid timezone:${timezone} What it means
Thrown by UptimeKumaServer.checkTimezone(timezone) when `dayjs.utc("2013-11-18 11:55").tz(timezone).format()` raises an exception — i.e. the timezone string is not a valid IANA zone identifier recognized by the dayjs timezone plugin. The probe date is arbitrary; only the tz() lookup matters.
Source
Thrown at server/uptime-kuma-server.js:465
/**
* Get the current offset
* @returns {string} Time offset
*/
getTimezoneOffset() {
return dayjs().format("Z");
}
/**
* Throw an error if the timezone is invalid
* @param {string} timezone Timezone to test
* @returns {void}
* @throws The timezone is invalid
*/
checkTimezone(timezone) {
try {
dayjs.utc("2013-11-18 11:55").tz(timezone).format();
} catch (e) {
throw new Error("Invalid timezone:" + timezone);
}
}
/**
* Set the current server timezone and environment variables
* @param {string} timezone Timezone to set
* @returns {Promise<void>}
*/
async setTimezone(timezone) {
this.checkTimezone(timezone);
await Settings.set("serverTimezone", timezone, "general");
process.env.TZ = timezone;
dayjs.tz.setDefault(timezone);
}
/**
* TODO: Listen logic should be moved to here
* @returns {Promise<void>}View on GitHub (pinned to 6b5ea01557)
Solutions
- Use a full IANA timezone identifier from the tz database (e.g. "America/New_York", "Europe/Berlin", "UTC").
- Populate the timezone picker from Intl.supportedValuesOf('timeZone') or a tz list rather than free text.
- In containers, install the tzdata package so dayjs can resolve zones.
- When setting TZ at boot, prefer getTimezone()'s fallback behavior by leaving it unset rather than forcing an invalid value.
Example fix
// before
process.env.TZ = "GMT+2"; // not an IANA zone
await server.setTimezone("EST"); // ambiguous abbreviation
// after
process.env.TZ = "Europe/Berlin";
await server.setTimezone("America/New_York");
// verify quickly:
try { new Intl.DateTimeFormat("en", { timeZone: tz }); } catch { /* invalid */ } Defensive patterns
Strategy: validation
Validate before calling
function isValidTimezone(tz) {
try { new Intl.DateTimeFormat("en-US", { timeZone: tz }); return true; } catch { return false; }
}
if (!isValidTimezone(tz)) throw new Error("Invalid timezone"); Type guard
const isIanaTimezone = (v) => typeof v === "string" && isValidTimezone(v);
Try / catch
try { server.checkTimezone(tz); } catch (e) { if (/Invalid timezone/.test(e.message)) tz = "UTC"; /* fallback */ } Prevention
- Always use full IANA identifiers (Europe/Berlin, America/New_York, UTC).
- Populate the picker from Intl.supportedValuesOf('timeZone').
- In containers, install tzdata so zones resolve.
When it happens
Trigger: setTimezone(timezone) (uptime-kuma-server.js:474) called from server.js:1527 (settings save, data.serverTimezone) or general-socket-handler.js:50 with an invalid timezone — e.g. "Foo/Bar", "GMT+2", "EST", a typo like "Amercia/New_York", or a bare offset string. getTimezone() also calls checkTimezone for process.env.TZ, settings, and the dayjs guess, but it wraps each call in try/catch with fallback, so only setTimezone propagates this error to the socket layer.
Common situations: Operator sets TZ env var to a non-IANA value at deploy time; user types a free-form timezone in the settings UI; settings.serverTimezone corrupted in the DB after a manual edit; running on a minimal container whose /usr/share/zoneinfo is stripped, causing otherwise-valid zones to be rejected.
Related errors
- Service Name is required.
- Invalid service name. Please use the internal Service Name (
- Invalid PM2 process name.
- Packet size must be between ${PING_PACKET_SIZE_MIN} and ${PI
- Per-ping timeout must be between ${PING_PER_REQUEST_TIMEOUT_
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/7310675712d659ab.
Report an issue: GitHub.