louislam/uptime-kuma · error · Error

Service Name is required.

Error message

Service Name is required.

What it means

Thrown by Monitor.validate() in server/model/monitor.js when a monitor of type "system-service" is created or updated with an empty system_service_name. The field is trimmed before the check, so a whitespace-only value also triggers it. Uptime-Kuma requires the systemd/init service unit name to query the host's service manager.

Source

Thrown at server/model/monitor.js:1697

                JSON.parse(this.headers);
            } catch (e) {
                throw new Error(`Headers must be valid JSON: ${e.message}`);
            }
        }

        if (this.accepted_statuscodes_json) {
            try {
                JSON.parse(this.accepted_statuscodes_json);
            } catch (e) {
                throw new Error(`Accepted status codes must be valid JSON: ${e.message}`);
            }
        }

        if (["system-service", "pm2"].includes(this.type)) {
            this.system_service_name = (this.system_service_name || "").trim();

            if (!this.system_service_name) {
                throw new Error(this.type === "pm2" ? "PM2 process name is required." : "Service Name is required.");
            }
        }

        if (this.type === "system-service" && !/^[a-zA-Z0-9._\-@]+$/.test(this.system_service_name)) {
            throw new Error("Invalid service name. Please use the internal Service Name (no spaces).");
        }

        if (this.type === "pm2" && /[\u0000-\u001F\u007F]/.test(this.system_service_name)) {
            throw new Error("Invalid PM2 process name.");
        }

        if (this.type === "ping") {
            // ping parameters validation
            if (this.packetSize && (this.packetSize < PING_PACKET_SIZE_MIN || this.packetSize > PING_PACKET_SIZE_MAX)) {
                throw new Error(
                    `Packet size must be between ${PING_PACKET_SIZE_MIN} and ${PING_PACKET_SIZE_MAX} (default: ${PING_PACKET_SIZE_DEFAULT})`
                );
            }

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Set system_service_name to the internal systemd unit name, e.g. "nginx.service" or "ssh".
  2. If building the payload programmatically, ensure the field is a non-empty string after .trim() before sending.
  3. Confirm the monitor type is actually "system-service" and not mislabeled as another type that does not use this field.

Example fix

// before
{ type: "system-service", system_service_name: "" }
// after
{ type: "system-service", system_service_name: "nginx.service" }
Defensive patterns

Strategy: validation

Validate before calling

function isValidSystemServiceName(name) {
  return typeof name === "string" && name.trim().length > 0;
}
if (monitor.type === "system-service" && !isValidSystemServiceName(monitor.system_service_name)) {
  throw new Error("system_service_name required before save");
}

Type guard

function isSystemServiceInput(m) {
  return m && m.type === "system-service" && typeof m.system_service_name === "string" && m.system_service_name.trim().length > 0;
}

Try / catch

try {
  await bean.validate();
} catch (e) {
  if (/Service Name is required/.test(e.message)) {
    return badRequest("system_service_name is required");
  }
  throw e;
}

Prevention

When it happens

Trigger: POST/PUT to the monitor save/update Socket.IO or REST endpoint with {type:"system-service", system_service_name:""} or {type:"system-service"} with the field omitted/whitespace. The branch is only entered for types in ["system-service","pm2"], and the ternary picks this exact message when type !== "pm2".

Common situations: User selects the "System Service" monitor type in the Uptime-Kuma UI but forgets to fill the service name field; or an API/automation script POSTs the monitor payload without mapping the service name. Migrating monitors where the field was previously nullable.

Related errors


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