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

  1. Use a full IANA timezone identifier from the tz database (e.g. "America/New_York", "Europe/Berlin", "UTC").
  2. Populate the timezone picker from Intl.supportedValuesOf('timeZone') or a tz list rather than free text.
  3. In containers, install the tzdata package so dayjs can resolve zones.
  4. 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

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


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