# Uptime Kuma User Guide

Uptime Kuma is a self-hosted monitoring tool that watches the health of your websites, APIs, servers, databases, containers, game servers, and other network endpoints. When something breaks, it alerts you through 93 notification channels. You run it on your own machine, inside Docker, or on a small VPS. It gives you a modern dashboard, public status pages, and fine-grained alerting with zero telemetry and zero external dependencies beyond what you configure.

This guide is for end users and operators who want to install, configure, and run Uptime Kuma day to day. If you are deploying at scale, customizing source, hardening security, or contributing, read the Admin Guide.

> [!NOTE]
> This guide documents Uptime Kuma **2.2.1** (commit `43b143c`, 2026-04-17). Uptime Kuma 2.x is a significant revision of 1.x; all version tags, defaults, and screenshots below refer to the 2.x line unless stated otherwise.

---

## 1. Quick Start

Get a monitor running in under three minutes.

### 1.1 Start the server

**Docker Compose (recommended)**

```bash
mkdir uptime-kuma && cd uptime-kuma
curl -o compose.yaml https://raw.githubusercontent.com/louislam/uptime-kuma/master/compose.yaml
docker compose up -d
```

**Docker run (single container)**

```bash
docker run -d --restart=always -p 3001:3001 \
  -v uptime-kuma:/app/data \
  --name uptime-kuma louislam/uptime-kuma:2
```

**Node.js (bare metal)**

```bash
git clone https://github.com/louislam/uptime-kuma.git
cd uptime-kuma
npm run setup
node server/server.js
```

Expected output (Docker):

```text
[+] Running 1/1
 ✔ Container uptime-kuma  Started
```

### 1.2 Open the web UI

Point a browser at:

```text
http://localhost:3001
```

The first visit shows the setup wizard.

### 1.3 Finish first-time setup

1. Choose a database backend (SQLite is the default and recommended for most users).
2. Create the admin username and password.
3. You land on an empty dashboard.

### 1.4 Add your first monitor

1. Click **Add New Monitor**.
2. Pick **HTTP(s)** as the monitor type.
3. Enter a friendly name (e.g., `My Website`).
4. Enter the URL (e.g., `https://example.com`).
5. Leave **Heartbeat Interval** at 60 seconds.
6. Click **Save**.

Within one heartbeat cycle you see a green status dot and the first data point on the ping chart.

> [!TIP]
> The first heartbeat fires immediately after saving — you do not have to wait 60 seconds to see whether a monitor is configured correctly.

---

## 2. Installation

Uptime Kuma ships as a Docker image, a Node.js application, or an embedded package with optional MariaDB. Choose the method that matches your environment.

### 2.1 Supported platforms

| Platform | Support |
|----------|---------|
| Debian, Ubuntu, Fedora, Arch, other major Linux distros | Supported |
| Windows 10 (x64), Windows Server 2012 R2 (x64) or higher | Supported |
| macOS (via Docker or Node.js) | Supported |
| FreeBSD, OpenBSD, NetBSD | Not supported |
| Replit, Heroku | Not supported |

> [!WARNING]
> Filesystems like **NFS** (Network File System) are **not** supported for the `/app/data` volume. Use a local directory or a Docker named volume. Running on NFS causes SQLite corruption and random crashes.

### 2.2 Requirements

| Component | Minimum | Notes |
|-----------|---------|-------|
| Node.js | `>= 20.4.0` | Versions below 18 and 20.0.x through 20.3.x are **banned** — the server exits immediately on start. |
| Docker | Any current | For Compose installs. |
| Git | Any | Required for Node.js install (`npm run setup`). |
| PM2 | Any | Recommended to keep the Node.js server alive. |
| Disk | ~250 MB | For the container image + SQLite database. |
| RAM | 256 MB | More for heavy workloads (100+ monitors). |
| Ports | `3001/tcp` | Default listen port; configurable. |

### 2.3 Docker Compose (recommended)

Create a working directory, download the sample Compose file, and start the stack.

```bash
mkdir uptime-kuma && cd uptime-kuma
curl -o compose.yaml https://raw.githubusercontent.com/louislam/uptime-kuma/master/compose.yaml
docker compose up -d
```

The reference `compose.yaml` shipped with the repo is:

```yaml
services:
  uptime-kuma:
    image: louislam/uptime-kuma:2
    restart: unless-stopped
    volumes:
      - ./data:/app/data
    ports:
      # <Host Port>:<Container Port>
      - "3001:3001"
```

> [!NOTE]
> The bind mount `./data:/app/data` stores the SQLite database, uploaded icons, screenshots, and Docker TLS certificates. Back up this directory to preserve your monitors and their history.

#### Docker Compose with Docker socket monitoring

If you want to monitor Docker containers, mount the Docker socket:

```yaml
services:
  uptime-kuma:
    image: louislam/uptime-kuma:2
    restart: unless-stopped
    volumes:
      - ./data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ports:
      - "3001:3001"
```

#### Docker Compose with TLS

If you want Uptime Kuma to serve HTTPS directly (without a reverse proxy):

```yaml
services:
  uptime-kuma:
    image: louislam/uptime-kuma:2
    restart: unless-stopped
    volumes:
      - ./data:/app/data
      - ./certs:/certs:ro
    ports:
      - "3001:3001"
    environment:
      - UPTIME_KUMA_SSL_KEY=/certs/key.pem
      - UPTIME_KUMA_SSL_CERT=/certs/cert.pem
```

### 2.4 Docker run (single container)

```bash
docker run -d --restart=always -p 3001:3001 \
  -v uptime-kuma:/app/data \
  --name uptime-kuma louislam/uptime-kuma:2
```

To expose the UI only on localhost (for example, behind a reverse proxy):

```bash
docker run -d --restart=always -p 127.0.0.1:3001:3001 \
  -v uptime-kuma:/app/data \
  --name uptime-kuma louislam/uptime-kuma:2
```

### 2.5 Non-Docker (Node.js + PM2)

```bash
git clone https://github.com/louislam/uptime-kuma.git
cd uptime-kuma
npm run setup
```

`npm run setup` checks out the tagged 2.2.1 release, installs production dependencies with `npm ci --omit dev --no-audit`, and downloads the pre-built frontend.

Run once to verify:

```bash
node server/server.js
```

Expected output:

```text
Welcome to Uptime Kuma
Your Node.js version: 20.x.x
...
[INFO] server: Listening on 3001
```

Then supervise with PM2:

```bash
npm install pm2 -g && pm2 install pm2-logrotate
pm2 start server/server.js --name uptime-kuma
pm2 startup && pm2 save
```

Useful PM2 commands:

```bash
pm2 monit              # Live console
pm2 logs uptime-kuma   # Tail logs
pm2 restart uptime-kuma
pm2 stop uptime-kuma
```

### 2.6 Windows installation (Node.js)

```powershell
git clone https://github.com/louislam/uptime-kuma.git
cd uptime-kuma
npm run setup
node server/server.js
```

For persistent service on Windows, consider using NSSM or PM2 on Windows:

```powershell
npm install pm2 -g
pm2 start server/server.js --name uptime-kuma
pm2 save
pm2-startup install
```

### 2.7 Updating Uptime Kuma

**Docker:**

```bash
docker pull louislam/uptime-kuma:2
docker compose down && docker compose up -d
```

**Node.js:**

```bash
cd uptime-kuma
git pull
npm run setup
pm2 restart uptime-kuma
```

> [!IMPORTANT]
> Always back up `./data/` (or your Docker volume) before upgrading. Database migrations run automatically and are not reversible.

### 2.8 Verify the install

- `docker ps` or `pm2 status` shows the process running.
- `curl -I http://localhost:3001` returns `HTTP/1.1 302 Found` (redirect to `/dashboard` or `/setup`).
- The web UI loads at `http://localhost:3001`.
- You completed the setup wizard and created an admin account.

---

## 3. Configuration

### 3.1 First-time database setup

On first boot (or when the data directory is empty), Uptime Kuma starts a **setup server** that asks two questions before the main application comes up.

#### Choose a database backend

| Backend | When to use |
|---------|-------------|
| **SQLite** | Default. Single-file, zero configuration, handles hundreds of monitors comfortably. |
| **MariaDB / MySQL** | Larger deployments, horizontal concerns, shared DB infrastructure. |
| **Embedded MariaDB** | Opt-in experiment — bundled MariaDB binary. Enable via `UPTIME_KUMA_ENABLE_EMBEDDED_MARIADB=1`. |

SQLite files live at `./data/kuma.db` by default. Configuration is written to `./data/db-config.json` after the wizard.

> [!IMPORTANT]
> If you provide the `UPTIME_KUMA_DB_TYPE` environment variable, the setup wizard is skipped and the value is written straight to `db-config.json`. This is the recommended path for container automation and CI/CD pipelines.

#### Create the admin account

Enter a username and a strong password. Uptime Kuma rejects weak passwords with:

```text
Password is too weak, please use a stronger password.
```

Minimum strength is validated by the `check-password-strength` library; aim for a mix of length, upper/lowercase, digits, and symbols.

After the wizard, Uptime Kuma restarts automatically (same port) and presents the normal login screen.

### 3.2 Environment variables (user-facing)

All environment variables are optional. Set them in your `docker-compose.yml`, `.env` file, or shell before starting the server.

| Variable | Default | Purpose |
|----------|---------|---------|
| `UPTIME_KUMA_HOST` | (all interfaces) | Bind hostname/IP. |
| `UPTIME_KUMA_PORT` | `3001` | Bind port. |
| `PORT` | `3001` | Alias for `UPTIME_KUMA_PORT` (only if `UPTIME_KUMA_PORT` is unset). |
| `HOST` | (system) | Alias for `UPTIME_KUMA_HOST` (not used on FreeBSD). |
| `DATA_DIR` | `./data/` | Base data directory. Must end with `/`. |
| `TZ` | system | Default timezone for the server (e.g., `America/New_York`). |
| `UPTIME_KUMA_SSL_KEY` / `SSL_KEY` | -- | Path to TLS private key. |
| `UPTIME_KUMA_SSL_CERT` / `SSL_CERT` | -- | Path to TLS certificate. |
| `UPTIME_KUMA_SSL_KEY_PASSPHRASE` / `SSL_KEY_PASSPHRASE` | -- | Passphrase for encrypted key. |
| `UPTIME_KUMA_CLOUDFLARED_TOKEN` | -- | Auto-start Cloudflared tunnel with this token. |
| `UPTIME_KUMA_WS_ORIGIN_CHECK` | `cors-like` | `cors-like` (default) or `bypass` (dev only). |
| `UPTIME_KUMA_DISABLE_FRAME_SAMEORIGIN` | unset | Set to any value to allow iframe embedding. |
| `UPTIME_KUMA_LOG_FORMAT` | unset | Set to `json` for structured logs. |
| `UPTIME_KUMA_HIDE_LOG` | unset | Suppress specific log categories (comma-separated). |
| `UPTIME_KUMA_ALLOW_ALL_CHROME_EXEC` | unset | Allow any Chrome binary for Real Browser monitors. |
| `NODE_TLS_REJECT_UNAUTHORIZED` | `1` | Set to `0` to skip TLS verification for self-signed certs (use with caution). |
| `UPTIME_KUMA_LOG_RESPONSE_BODY_MONITOR_ID` | unset | Log the full response body for a specific monitor ID (debugging). |
| `UPTIME_KUMA_DB_POOL_MAX_CONNECTIONS` | `10` | Max DB pool connections (capped at `100`). |
| `NODE_ENV` | `production` | Set to `development` to enable debug UI and dev endpoints. |

Database-specific variables (`UPTIME_KUMA_DB_TYPE`, `UPTIME_KUMA_DB_HOSTNAME`, `UPTIME_KUMA_DB_PORT`, `UPTIME_KUMA_DB_NAME`, `UPTIME_KUMA_DB_SOCKET`, `UPTIME_KUMA_DB_PASSWORD`, `UPTIME_KUMA_DB_PASSWORD_FILE`) are covered in the Admin Guide.

### 3.3 Command-line flags

Flags can be passed directly to `node server/server.js`:

| Flag | Equivalent env var |
|------|--------------------|
| `--host` | `UPTIME_KUMA_HOST` |
| `--port` | `UPTIME_KUMA_PORT` |
| `--ssl-key` | `UPTIME_KUMA_SSL_KEY` |
| `--ssl-cert` | `UPTIME_KUMA_SSL_CERT` |
| `--ssl-key-passphrase` | `UPTIME_KUMA_SSL_KEY_PASSPHRASE` |
| `--data-dir` | `DATA_DIR` |
| `--cloudflared-token` | `UPTIME_KUMA_CLOUDFLARED_TOKEN` |
| `--disable-frame-sameorigin` | `UPTIME_KUMA_DISABLE_FRAME_SAMEORIGIN` |
| `--demo` | (runs in demo mode, read-only) |

### 3.4 General settings

Navigate to **Settings** in the top-right menu. Key panels:

| Settings panel | What it controls |
|----------------|------------------|
| **General** | Entry page, search engine indexing, timezone, keepalive intervals |
| **Appearance** | Theme (light/dark), primary color |
| **Notifications** | Notification channel management |
| **Security** | Password change, 2FA, OIDC/OAuth, disable auth |
| **Reverse Proxy** | `trustProxy` toggle for `X-Forwarded-*` header handling |
| **Tags** | Create and manage tags for monitor organization |
| **Monitor History** | Heartbeat retention settings |
| **Docker** | Docker host connections for container monitoring |
| **Remote Browsers** | Chromium endpoints for Real Browser monitors |
| **Proxies** | HTTP/SOCKS proxy definitions |
| **API Keys** | Create, manage, and revoke API keys |
| **About** | Version info, check for updates |

### 3.5 Timezone configuration

Set the server timezone via the `TZ` environment variable:

```yaml
environment:
  - TZ=Europe/London
```

Per-user timezone is chosen under **Settings** and only affects how timestamps render in the UI. Invalid timezones are rejected with `Invalid timezone:`.

### 3.6 Search engine indexing

Under **Settings → General**, toggle **Search Engine Indexing**. When disabled, the `robots.txt` response changes from allowing all to:

```text
User-agent: *
Disallow: /
```

### 3.7 Entry page

Under **Settings → General**, set the entry page. You can make the root URL (`/`) redirect to:

- The dashboard (default)
- A specific status page (e.g., `statusPage-public`)

If a custom domain is mapped to a status page, that mapping takes priority over this setting.

---

## 4. Core Usage

### 4.1 Dashboard overview

The dashboard is split into three areas:

- **Left sidebar** — list of monitors, grouped or sorted, with search and filter.
- **Main pane** — details of the selected monitor: status, ping chart, event list, certificate info, response-time graph, and uptime stats for 24 h, 30 d, 1 y, and all-time.
- **Top bar** — add monitor, theme toggle, language switch, and settings.

### 4.2 Monitor types

Uptime Kuma ships with 30+ monitor types. Each type checks a different kind of service.

#### HTTP / HTTPS monitors

| Type | What it checks |
|------|----------------|
| **HTTP(s)** | HTTP status code, optional TLS certificate, optional body keyword, optional JSON query. |
| **HTTP(s) - Keyword** | HTTP body contains (or does not contain) a keyword string. |
| **HTTP(s) - JSON Query** | JSONata expression evaluated against the JSON response body. |

#### Network monitors

| Type | What it checks |
|------|----------------|
| **TCP** | TCP connect to a host and port. |
| **Ping** | ICMP ping; configurable packet size. |
| **DNS** | DNS record resolves to an expected value. Supports A, AAAA, CNAME, MX, NS, PTR, SOA, SRV, TXT, CAA. |
| **TLS Certificate** | Certificate validity and expiration. |

#### Database monitors

| Type | What it checks |
|------|----------------|
| **MySQL / MariaDB** | MySQL ping or custom query. |
| **PostgreSQL** | PostgreSQL ping or custom query. |
| **MongoDB** | MongoDB connection and optional command. |
| **Microsoft SQL Server** | MSSQL ping or custom query. |
| **Oracle DB** | Oracle DB ping or custom query. |
| **Redis** | Redis `PING` command. |

#### Messaging / queue monitors

| Type | What it checks |
|------|----------------|
| **MQTT** | MQTT subscribe and verify message content. Supports `mqtt://` connections. |
| **RabbitMQ** | RabbitMQ management API health check. |
| **Kafka Producer** | Kafka producer heartbeat. |

#### Infrastructure monitors

| Type | What it checks |
|------|----------------|
| **Docker Container** | Container running status on a configured Docker host. |
| **System Service** | OS service status (systemd on Linux, Windows Service on Windows). |
| **Tailscale Ping** | Ping a Tailscale peer by hostname or IP. |

#### Protocol monitors

| Type | What it checks |
|------|----------------|
| **gRPC - Keyword** | gRPC method call with keyword in response. |
| **WebSocket Upgrade** | WebSocket upgrade handshake success. |
| **SMTP** | SMTP greeting and optional STARTTLS negotiation. |
| **SNMP** | SNMP OID polling (v1, v2c, v3). |
| **SIP (OPTIONS)** | SIP OPTIONS probe via `sipsak`. |
| **RADIUS** | RADIUS authentication check. |

#### Special monitors

| Type | What it checks |
|------|----------------|
| **Push** | Passive — your script pushes heartbeats to Uptime Kuma on a schedule. |
| **Real Browser** | Headless Chromium renders the page; detects JS-dependent failures. |
| **GameDig** | Game server query (Minecraft, Valheim, CS2, etc.) via GameDig library. |
| **Steam Game Server** | Steam-specific game server query. |
| **Globalping** | Distributed probe via the Globalping network (ping, HTTP, DNS, traceroute from worldwide probes). |
| **Group** | Logical grouping; aggregates child monitor status. |
| **Manual** | Human-toggled up/down. |

> [!TIP]
> If you need HTTP plus a response-body assertion, pick **HTTP(s) - Keyword** or **HTTP(s) - JSON Query** rather than building your own script. The built-ins already handle retries, heartbeats, and notifications.

### 4.3 Adding a monitor

Click **Add New Monitor**. Choose a type, fill the type-specific fields, set timing, then save.

#### Common fields (all monitor types)

| Field | Meaning |
|-------|---------|
| **Friendly Name** | Shown in the dashboard and notifications. |
| **Heartbeat Interval** | Seconds between checks. Minimum **20 seconds**. Maximum defined by `MAX_INTERVAL_SECOND`. |
| **Retries** | Consecutive failures before a monitor is marked **down**. |
| **Heartbeat Retry Interval** | Seconds between retries (also has min/max enforcement). |
| **Resend Notification if Down X times** | Re-alert cadence for a sustained outage. Set `0` for alert only on state change. |
| **Upside Down Mode** | Invert — down is success, up is failure. |
| **Tags** | Attach tags for filtering and organization. |
| **Description** | Free-text description visible on status pages. |
| **Parent Group** | Assign to a Group monitor. |

#### HTTP-specific fields

| Field | Meaning |
|-------|---------|
| **URL** | The full URL to request. |
| **Max. Redirects** | `0` disables following redirects. |
| **Accepted Status Codes** | List such as `200-299`. All values must be strings. |
| **Request Method** | GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. |
| **Request Body** | For POST/PUT/PATCH requests. |
| **Headers** | JSON object of custom HTTP headers. |
| **Authentication** | Basic, NTLM, or mTLS. |
| **Certificate Expiry Notification** | Alert when the cert nears expiration (days threshold). |
| **Proxy** | Route through a configured proxy. |
| **Response Body Max Length** | Limit stored response body (minimum 0, maximum enforced). |

#### DNS-specific fields

| Field | Meaning |
|-------|---------|
| **Hostname** | Domain to resolve. |
| **DNS Resolver Server** | Custom DNS server (IP). |
| **Record Type** | A, AAAA, CNAME, MX, NS, PTR, SOA, SRV, TXT, CAA. |
| **Conditions** | Expression-based conditions on the DNS response (see the Monitor Conditions section below). |

#### Database-specific fields (MySQL, PostgreSQL, MSSQL, Oracle)

| Field | Meaning |
|-------|---------|
| **Connection String** or individual fields | Host, port, database name, username, password. |
| **Query** | Optional SQL query. If provided, the result is evaluated against conditions. |

### 4.4 Monitor conditions

Uptime Kuma 2.x introduced a condition expression system. Instead of simple keyword matching, you can build complex conditions with operators:

**String operators:** Equals, Not Equals, Contains, Not Contains, Starts With, Not Starts With, Ends With, Not Ends With.

**Numeric operators:** Equals, Not Equals, Less Than, Greater Than, Less Than or Equal To, Greater Than or Equal To.

Conditions can be grouped with AND/OR logic (via `ConditionExpressionGroup`). This is used by DNS monitors, database query monitors, and SNMP monitors among others.

### 4.5 Pausing, resuming, editing, deleting

- **Pause** — the monitor stops firing heartbeats and notifications until resumed.
- **Resume** — resumes heartbeats from the next cycle.
- **Edit** — change any field. Changes take effect on the next heartbeat.
- **Delete** — removes the monitor and all heartbeat history permanently.
- **Clone** — duplicates the monitor configuration with a new name.

> [!CAUTION]
> Delete cannot be undone. Heartbeats, certificate history, and related notification logs are permanently purged. Export your data first if you need to keep historical records.

### 4.6 Tags

Tags group related monitors without nesting them. Create tags in **Settings → Tags**, then attach them when editing a monitor. Each tag has:

- A name
- A color (displayed as a colored pill on the dashboard)
- An optional value per monitor (e.g., tag "Environment" with value "production")

Tags appear on the dashboard and can filter the monitor list.

### 4.7 Groups

A **Group** monitor is a parent that aggregates the status of its children.

- Its own status is **down** if any child is down (logical OR across children).
- Useful for a "website" that comprises web + API + database.
- Pausing the group does **not** pause the children (community-tracked behavior, issue #7242).
- Groups can be nested (a group can contain other groups).

### 4.8 Incidents

From the **Status Page** editor, post a short incident notice (title + content). Incidents appear on the public status page with a timestamp.

- Use for scheduled maintenance, known outages, or post-mortem recaps.
- Incidents do not change monitor state; they are purely informational overlays.
- The status page validates that both title and content are provided (`Please input title` / `Please input content`).

### 4.9 Maintenance windows

Create maintenance windows to silence notifications and mark monitors as "in maintenance" on a recurring schedule.

| Strategy | Meaning |
|----------|---------|
| **Single Maintenance Window** | One-time window with start/end datetime. |
| **Manual** | Start/stop by hand via the UI. |
| **Recurring: Day of Week** | Weekly schedule (e.g., every Sunday 03:00 to 04:00). |
| **Recurring: Day of Month** | Monthly by day number. |
| **Recurring: Weekday of Month** | "Second Tuesday of each month." |
| **Cron** | Any cron expression (powered by the `croner` library). |

Attach monitors and status pages to the maintenance. During the window, monitors show a wrench icon and notifications are suppressed. Invalid dates produce `Invalid start date` or `Invalid end date`.

---

## 5. Common Tasks

### 5.1 Monitor a public website

1. Add an **HTTP(s)** monitor.
2. URL: `https://example.com`.
3. Accepted Status Codes: `200-299`.
4. Heartbeat Interval: `60`.
5. Retries: `2`, Retry Interval: `60`.
6. Attach a Slack or email notification channel.
7. Save.

### 5.2 Monitor an internal API with JSON assertion

1. Add an **HTTP(s) - JSON Query** monitor.
2. URL: `https://api.internal/healthz`.
3. JSON Path / Expression: `status` (JSONata syntax).
4. Expected Value: `ok`.
5. Add an auth header under **HTTP Options → Headers** (e.g., `{"Authorization": "Bearer <token>"}`).
6. Save.

### 5.3 Monitor a TCP service

1. Add a **TCP** monitor.
2. Hostname: `db.internal`.
3. Port: `5432`.
4. Heartbeat: `30` seconds.
5. Save.

### 5.4 Monitor DNS resolution

1. Add a **DNS** monitor.
2. Hostname: `example.com`.
3. DNS Resolver Server: `8.8.8.8` (or leave blank for system default).
4. Record Type: `A`.
5. Add a condition: the resolved value must contain your expected IP.
6. Save.

> [!WARNING]
> DNS monitors with long TXT records (such as DKIM keys) may fail condition evaluation. This is a known issue tracked under #7280. Consider using a Contains condition instead of exact match for long TXT records.

### 5.5 Push monitor from a script (passive)

Uptime Kuma can be the receiver — your script pushes a heartbeat on a schedule.

1. Add a **Push** monitor. Copy the generated Push URL.
2. The URL format is: `https://your-kuma/api/push/<token>?status=up&msg=OK&ping=`
3. Both GET and POST are accepted.

#### Push URL parameters

| Parameter | Required | Description |
|-----------|----------|-------------|
| `status` | Yes | `up` or `down` |
| `msg` | No | Status message (e.g., `OK`, `Backup completed`) |
| `ping` | No | Response time in milliseconds (integer, must be between 0 and the configured maximum) |

#### Bash + curl

```bash
#!/bin/bash
PUSH_URL="https://example.com/api/push/key?status=up&msg=OK&ping="
INTERVAL=60

while true; do
    curl -s -o /dev/null $PUSH_URL
    echo "Pushed!"
    sleep $INTERVAL
done
```

#### Python

```python
import urllib.request
import time

push_url = "https://example.com/api/push/key?status=up&msg=OK&ping="
interval = 60

while True:
    urllib.request.urlopen(push_url)
    print("Pushed!\n")
    time.sleep(interval)
```

#### PowerShell

```powershell
$pushURL = "https://example.com/api/push/key?status=up&msg=OK&ping="
$interval = 60

while ($true) {
    $res = Invoke-WebRequest -Uri $pushURL
    Write-Host "Pushed!"
    Start-Sleep -Seconds $interval
}
```

#### JavaScript (Node.js >= 18, Deno, Bun)

```javascript
const pushURL = "https://example.com/api/push/key?status=up&msg=OK&ping=";
const interval = 60;

const push = async () => {
    await fetch(pushURL);
    console.log("Pushed!");
};

push();
setInterval(push, interval * 1000);
```

#### TypeScript (Deno, Bun, ts-node)

```typescript
const pushURL: string = "https://example.com/api/push/key?status=up&msg=OK&ping=";
const interval: number = 60;

const push = async () => {
    await fetch(pushURL);
    console.log("Pushed!");
};

push();
setInterval(push, interval * 1000);
```

#### Go

```go
package main

import (
	"fmt"
	"net/http"
	"time"
)

func main() {
	const PushURL = "https://example.com/api/push/key?status=up&msg=OK&ping="
	const Interval = 60

	for {
		_, err := http.Get(PushURL)
		if err == nil {
			fmt.Println("Pushed!")
		}
		time.Sleep(Interval * time.Second)
	}
}
```

#### Java

```java
import java.net.HttpURLConnection;
import java.net.URL;

class PushMonitor {
    public static final String PUSH_URL = "https://example.com/api/push/key?status=up&msg=OK&ping=";
    public static final int INTERVAL = 60;

    public static void main(String[] args) {
        while (true) {
            try {
                URL url = new URL(PUSH_URL);
                HttpURLConnection con = (HttpURLConnection) url.openConnection();
                con.setRequestMethod("GET");
                con.getResponseCode();
                con.disconnect();
                System.out.println("Pushed!");
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                Thread.sleep(INTERVAL * 1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
```

#### C#

```csharp
using System;
using System.Net;
using System.Threading;

class PushMonitor
{
    const string PushURL  = "https://example.com/api/push/key?status=up&msg=OK&ping=";
    const int Interval = 60;

    static void Main(string[] args)
    {
        while (true)
        {
            WebClient client = new WebClient();
            client.DownloadString(PushURL);
            Console.WriteLine("Pushed!");
            Thread.Sleep(Interval * 1000);
        }
    }
}
```

#### PHP

```php
<?php
const PUSH_URL = "https://example.com/api/push/key?status=up&msg=OK&ping=";
const interval = 60;

while (true) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, PUSH_URL);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_exec($ch);
    curl_close($ch);
    echo "Pushed!\n";
    sleep(interval);
}
```

#### Docker (pre-built push container)

```bash
docker run -d --restart=always --name uptime-kuma-push \
  louislam/uptime-kuma:push \
  "https://example.com/api/push/key?status=up&msg=OK&ping=" 60
```

### 5.6 Monitor a Docker container

1. **Settings → Docker Hosts → Setup Docker Host**.
2. Choose connection type:
   - **Unix socket**: `/var/run/docker.sock` (mount into the container with `-v /var/run/docker.sock:/var/run/docker.sock:ro`).
   - **TCP**: `tcp://docker-host:2376` with optional TLS.
3. Test and save.
4. Add a **Docker Container** monitor and pick the host plus the container name.

### 5.7 Monitor a game server

1. Add a **GameDig** monitor.
2. Game type: pick from the GameDig catalog (Minecraft, Valheim, Counter-Strike, etc.).
3. Host / Port.
4. Save. A probe is issued every heartbeat.

For Steam servers specifically, use the **Steam Game Server** type with the Steam API key configured.

### 5.8 Monitor a database

#### MySQL / MariaDB

1. Add a **MySQL** monitor.
2. Enter hostname, port (default `3306`), username, password, database name.
3. Optionally add a query (e.g., `SELECT 1`). If the query returns results not meeting conditions, the monitor goes down.
4. Save.

#### PostgreSQL

1. Add a **PostgreSQL** monitor.
2. Enter connection string or individual fields.
3. Optional query with conditions.
4. Save.

#### MongoDB

1. Add a **MongoDB** monitor.
2. Enter the connection string (e.g., `mongodb://user:pass@host:27017/dbname`).
3. Optionally add a MongoDB command. If the command fails, `MongoDB command failed` is reported.
4. Save.

#### Redis

1. Add a **Redis** monitor.
2. Enter hostname and port (default `6379`).
3. Uptime Kuma sends a `PING` command and expects `PONG`.
4. Save.

### 5.9 Monitor an MQTT broker

1. Add an **MQTT** monitor.
2. Enter the MQTT broker URL (e.g., `mqtt://broker.example.com:1883`).
3. Choose a check type: **Keyword** or **JSON Query**.
4. Provide the topic to subscribe to and the expected message content.
5. Save.

> [!NOTE]
> MQTT monitors currently do not accept `mqtts://` URLs directly (issue #7286). Use `mqtt://` with the appropriate port for TLS-wrapped connections, or configure a proxy.

### 5.10 Monitor with headless browser (Real Browser)

1. Configure a remote browser: **Settings → Remote Browsers → Add**.
2. Enter the Chromium WebSocket endpoint (e.g., `ws://chromium:3000`).
3. Test and save.
4. Add a **Real Browser** monitor. Select the remote browser.
5. Enter the URL. Uptime Kuma renders the page in headless Chromium.

This catches JavaScript-dependent failures that HTTP monitors miss (SPA apps, dynamic content).

If no Chromium executable is found: `Chromium not found, please specify Chromium executable path in the settings page.`

### 5.11 Monitor a systemd service or Windows service

1. Add a **System Service** monitor.
2. Enter the service name (e.g., `nginx` on Linux, `W3SVC` on Windows).
3. Save.

Service names must contain only alphanumeric characters and certain special characters. Invalid names produce `Invalid service name`.

System service monitoring is only supported on Linux (systemd) and Windows. Other platforms produce `System Service monitoring is not supported on <platform>`.

### 5.12 Monitor via Tailscale

1. Add a **Tailscale Ping** monitor.
2. Enter the Tailscale hostname or IP of the peer.
3. Save.

The Tailscale CLI must be available on the host running Uptime Kuma. Errors include:
- `Ping timed out` — peer is unreachable.
- `Nonexistant or inaccessible due to ACLs` — Tailscale ACLs block the connection.
- `Tailscale only works if used on other machines` — you cannot ping yourself.

### 5.13 Monitor with SNMP

1. Add an **SNMP** monitor.
2. Enter hostname, port (default `161`), community string (v1/v2c) or username (v3).
3. Enter the OID to poll.
4. Set conditions on the returned value.
5. Save.

For SNMPv3: `SNMPv3 username is required`.

### 5.14 Monitor SMTP servers

1. Add an **SMTP** monitor.
2. Enter hostname and port (default `25`, or `587` for submission, `465` for SMTPS).
3. Optionally enable STARTTLS verification.
4. Save.

If the SMTP greeting fails: `SMTP connection doesn't...`

### 5.15 Monitor with SIP OPTIONS

1. Add a **SIP-Options** monitor.
2. Enter the SIP URI target.
3. Uptime Kuma uses `sipsak` to send an OPTIONS probe.
4. Save.

Requires `sipsak` installed on the host. `No output from sipsak` indicates the binary is missing or the target is unreachable.

### 5.16 Monitor with Globalping

1. Add a **Globalping** monitor.
2. Choose the check type: Ping, HTTP, DNS, or Traceroute.
3. Enter the target.
4. Select probe locations (continents, countries, or specific probes).
5. Save.

Globalping distributes checks across worldwide probes. Rate-limiting by the Globalping API produces `Failed to create measurement` errors. Consider adding a Globalping API token under the monitor settings.

### 5.17 Monitor gRPC services

1. Add a **gRPC - Keyword** monitor.
2. Enter the gRPC server address and port.
3. Specify the service name and method.
4. Enter the proto file content or URL.
5. Set the keyword to match in the response.
6. Save.

### 5.18 Monitor WebSocket endpoints

1. Add a **WebSocket Upgrade** monitor.
2. Enter the WebSocket URL (e.g., `wss://echo.websocket.org`).
3. The monitor attempts the WebSocket upgrade handshake.
4. Save.

### 5.19 Build a status page for customers

1. **Status Pages → New Status Page**.
2. Slug: e.g., `public` (only letters, numbers, hyphens). Invalid slugs produce `Invalid Slug`.
3. Select the monitors to expose in groups/sections.
4. Upload a PNG logo (`Only allowed PNG logo.`).
5. Set a title, description, and optional custom footer.
6. Enable **Show Certificate Expiry**, **Show Tags** as desired.
7. Save. Public URL: `https://your-kuma/status/public`.
8. (Optional) Map a custom domain under **Settings → Domain Names**.

#### Status page endpoints

| Path | What it returns |
|------|-----------------|
| `GET /status/:slug` | Rendered HTML status page |
| `GET /status/:slug/rss` | RSS feed of recent incidents |
| `GET /api/status-page/:slug` | Page metadata + monitor list (JSON) |
| `GET /api/status-page/heartbeat/:slug` | Latest heartbeats (JSON) |
| `GET /api/status-page/:slug/manifest.json` | PWA manifest |
| `GET /api/status-page/:slug/incident-history` | Incident list (JSON) |
| `GET /api/status-page/:slug/badge` | SVG status badge |

#### Custom domain for a status page

1. Point your DNS A record to your Uptime Kuma server IP.
2. In **Settings → Domain Names**, add the domain and map it to the status page slug.
3. When a request arrives on that domain, Uptime Kuma serves the mapped status page directly.

### 5.20 Set up a weekly maintenance window

1. **Maintenance → New Maintenance**.
2. Title: "Weekly Server Maintenance".
3. Strategy: **Recurring: Day of Week**.
4. Weekday: Sunday; Start: `03:00`; End: `04:00`.
5. Attach the affected monitors and status pages.
6. Save. Notifications are suppressed during the window.

### 5.21 Set up a monthly maintenance window

1. **Maintenance → New Maintenance**.
2. Strategy: **Recurring: Day of Month**.
3. Day: 1st; Start: `02:00`; End: `04:00`.
4. Attach monitors.
5. Save.

### 5.22 Set up a cron-based maintenance window

1. **Maintenance → New Maintenance**.
2. Strategy: **Cron**.
3. Cron expression: `0 3 * * 0` (every Sunday at 3 AM).
4. Duration: 60 minutes.
5. Save.

### 5.23 Create and use tags

1. **Settings → Tags → Add Tag**.
2. Name: `Production`, Color: red.
3. Add another: `Staging`, Color: yellow.
4. Edit monitors and assign tags with optional values (e.g., tag `Region`, value `us-east-1`).
5. Use the tag filter on the dashboard to view only production monitors.

### 5.24 Set up notification channels

1. **Settings → Notifications → Setup Notification**.
2. Pick a provider from the dropdown (93 available).
3. Fill provider-specific fields.
4. Click **Test** to send a sample alert.
5. Optionally **Apply on all existing monitors**.
6. Save.

### 5.25 Configure Discord notifications

1. In Discord, create a webhook in your channel settings.
2. In Uptime Kuma, add a **Discord** notification.
3. Paste the webhook URL.
4. Customize the bot display name and prefix message.
5. Test and save.

### 5.26 Configure Slack notifications

1. Create a Slack incoming webhook or Slack app.
2. In Uptime Kuma, add a **Slack** notification.
3. Paste the webhook URL.
4. Choose the channel and customize the message format.
5. Test and save.

### 5.27 Configure Telegram notifications

1. Create a bot via BotFather and get the bot token.
2. Get your chat ID (message the bot, then check via the API).
3. In Uptime Kuma, add a **Telegram** notification.
4. Paste bot token and chat ID.
5. Test and save.

### 5.28 Configure email (SMTP) notifications

1. In Uptime Kuma, add an **SMTP** notification.
2. Enter SMTP host, port, username, password.
3. Set from/to addresses.
4. Enable TLS/STARTTLS as needed.
5. Test and save.

### 5.29 Configure PagerDuty notifications

1. In PagerDuty, create a service and get the integration key.
2. In Uptime Kuma, add a **PagerDuty** notification.
3. Paste the integration key.
4. Test and save. Down events trigger PagerDuty incidents.

### 5.30 Configure webhook notifications

1. Add a **Webhook** notification.
2. Enter the target URL.
3. Choose content type (JSON or form-encoded).
4. Optionally add custom headers as JSON (`Additional Headers is not a valid JSON` if malformed).
5. Test and save.

This is the generic escape hatch for integrating with any system that accepts HTTP webhooks.

### 5.31 Set up a proxy for outbound monitoring

1. **Settings → Proxies → Add Proxy**.
2. Protocol: HTTP, HTTPS, SOCKS4, or SOCKS5.
3. Enter host, port, and optional auth.
4. Test and save.
5. In each monitor, select the proxy under **Advanced → Proxy**.

### 5.32 Use badges in your README

Embed live status badges in your GitHub README, wiki, or any Markdown file:

```markdown
![Status](https://your-kuma/api/badge/1/status)
![Uptime](https://your-kuma/api/badge/1/uptime/720)
![Ping](https://your-kuma/api/badge/1/ping/24)
```

#### Available badge endpoints

| Badge | URL |
|-------|-----|
| Status (up/down) | `/api/badge/:id/status` |
| Uptime percentage | `/api/badge/:id/uptime/:duration?` |
| Ping (latest) | `/api/badge/:id/ping/:duration?` |
| Average response time | `/api/badge/:id/avg-response/:duration?` |
| Certificate expiry | `/api/badge/:id/cert-exp` |
| Response time | `/api/badge/:id/response` |

#### Duration format

`:duration` accepts hours (`24h`), minutes (`60m`), or days (`7d`).

| Unit | Maximum | Error if exceeded |
|------|---------|-------------------|
| Hours | 720 | `The maximum number of hours is 720` |
| Minutes | 1440 | `The maximum number of minutes is 1440` |
| Days | 365 | `The maximum number of days is 365` |

### 5.33 Export and import monitors

1. **Settings → Backup → Export**. A JSON file is downloaded containing all monitors, notifications, proxies, and status pages.
2. To import: **Settings → Backup → Import**. Select the JSON file.
3. Choose whether to overwrite existing monitors or merge.

### 5.34 Set up Cloudflare Tunnel

1. Create a Cloudflare Tunnel in your Cloudflare dashboard and get the token.
2. Set `UPTIME_KUMA_CLOUDFLARED_TOKEN` in your environment or pass `--cloudflared-token`.
3. Uptime Kuma automatically starts the tunnel on boot.
4. Alternatively, manage tunnels from the UI: **Settings → Cloudflare Tunnels** (accessible via Socket.IO handler).

### 5.35 Enable Prometheus metrics

Uptime Kuma exposes a `/metrics` endpoint in Prometheus format (via `prom-client` + `prometheus-api-metrics`). The endpoint is protected by basic auth using the first user's credentials.

Add to your `prometheus.yml`:

```yaml
scrape_configs:
  - job_name: 'uptime-kuma'
    basic_auth:
      username: '<admin-username>'
      password: '<admin-password>'
    static_configs:
      - targets: ['your-kuma:3001']
```

### 5.36 Monitor with upside-down mode

For services that should be **down** (e.g., a decommissioned endpoint that must stay offline):

1. Add the appropriate monitor type.
2. Enable **Upside Down Mode**.
3. The monitor reports **up** when the target is unreachable and **down** when it responds.

### 5.37 Monitor certificate expiry

1. Add an **HTTP(s)** or **TLS Certificate** monitor.
2. Enable **Certificate Expiry Notification**.
3. Set the notification threshold (e.g., 30 days before expiry).
4. Attach a notification channel.

The monitor displays full certificate chain details: subject, issuer, serial, valid-from, valid-to, days remaining, and fingerprint.

### 5.38 Monitor domain expiry (RDAP/WHOIS)

HTTP monitors can track domain registration expiry via RDAP. The monitor displays days until domain expiration and can trigger notifications. Limitations:

- Only supported on HTTP(s) monitor types (`domain_expiry_unsupported_monitor_type` for others).
- The domain must have a valid RDAP endpoint (`domain_expiry_unsupported_unsupported_tld_no_rdap_endpoint` if the TLD lacks one).
- ICANN TLDs may produce `domain_expiry_unsupported_is_icann`.

### 5.39 Use the manual monitor

1. Add a **Manual** monitor.
2. Toggle status manually from the dashboard.
3. Useful for tracking things that cannot be auto-checked (e.g., "office printer status" or "vendor SLA compliance").

### 5.40 Monitor RabbitMQ

1. Add a **RabbitMQ** monitor.
2. Enter the management API nodes as JSON: `["http://rabbitmq:15672"]`.
3. Enter username and password.
4. Uptime Kuma queries the management API health check.
5. If all nodes fail: `All X nodes failed because...`.

Invalid node JSON produces `Invalid RabbitMQ Nodes`. Empty list produces `No RabbitMQ nodes configured`.

---

## 6. Troubleshooting

### 6.1 Error: `Your Node.js version: X is not supported`

**Cause.** Node.js is below version 18, or in the 20.0.x through 20.3.x range which has known bugs.
**Solution.** Upgrade to Node.js `>= 20.4.0`. Reinstall Uptime Kuma with `npm run setup` afterwards.
**Prevention.** Pin Node.js via NVM and follow the LTS track.

### 6.2 Error: `Knex: Timeout acquiring a connection`

**Cause.** The database connection pool is saturated — usually MariaDB/MySQL under heavy load (issues #7260, #6486).
**Solution.** Increase `UPTIME_KUMA_DB_POOL_MAX_CONNECTIONS` (default `10`, capped at `100`). Check for long-running queries. Restart Uptime Kuma.
**Prevention.** Monitor your database server separately. Consider using a connection pooler.

### 6.3 Error: `user not found, have you installed?`

**Cause.** You ran `npm run remove-2fa` or `npm run reset-password` before completing first-time setup.
**Solution.** Run Uptime Kuma normally, finish the setup wizard, then rerun the script.
**Prevention.** Only use these scripts on a running, initialized install.

### 6.4 Error: `Password is too weak, please use a stronger password.`

**Cause.** Password failed the strength check during setup or reset.
**Solution.** Use at least 12 characters with mixed case, digits, and symbols.
**Prevention.** Use a password manager.

### 6.5 Error: `Invalid db-config.json, it must be an object`

**Cause.** `./data/db-config.json` is malformed (manual edit, partial write, disk corruption).
**Solution.** Delete `db-config.json`, restart. The setup wizard re-runs.
**Prevention.** Never edit `db-config.json` by hand; use environment variables.

### 6.6 Error: `Invalid db-config.json, type must be a string`

**Cause.** The `type` field is missing or not a string in `db-config.json`.
**Solution.** Restore from backup or delete the file so setup re-runs.
**Prevention.** Back up `./data/` before upgrades.

### 6.7 Error: `Unknown Database type:`

**Cause.** `UPTIME_KUMA_DB_TYPE` set to an unsupported value.
**Solution.** Use one of: `sqlite`, `mariadb`, `mysql`, `mssql`, `postgres`, `embedded-mariadb`.

### 6.8 Error: `Both UPTIME_KUMA_DB_PASSWORD and UPTIME_KUMA_DB_PASSWORD_FILE are set`

**Cause.** You set both the direct env var and the `_FILE` Docker secret variant.
**Solution.** Pick one. Prefer `_FILE` for Docker Swarm / Kubernetes secrets.

### 6.9 Error: `docker host not found`

**Cause.** Docker Container monitor references a host that no longer exists or was never configured.
**Solution.** Re-add the Docker host under **Settings → Docker Hosts**. For Unix sockets, mount `/var/run/docker.sock` into the container.

### 6.10 Error: `Connection to Docker daemon timed out.`

**Cause.** The Docker daemon did not respond within 30 seconds.
**Solution.** Check that Docker is running. For TCP connections, verify firewall rules and TLS configuration.

### 6.11 Error: `Invalid Docker response, is it Docker really a daemon?`

**Cause.** The endpoint responds but is not the Docker API (maybe Portainer, Swarm UI, or a random HTTP service).
**Solution.** Point the Docker host at the real Docker socket or API endpoint.

### 6.12 Error: `Accepted status codes are not all strings`

**Cause.** A bulk import or API call passed numeric status codes instead of strings.
**Solution.** Quote all codes: `"200"` or `"200-299"` instead of bare `200`.

### 6.13 Error: `Invalid period.`

**Cause.** A chart or badge request used an invalid period parameter.
**Solution.** Use documented values: `1h`, `24h`, `7d`, `30d`, `1y`.

### 6.14 Error: `You do not own this monitor.`

**Cause.** Monitor ownership mismatch in multi-session scenarios.
**Solution.** Log in as the monitor owner.

### 6.15 Error: `Permission denied.`

**Cause.** An unauthenticated Socket.IO request tried a privileged action.
**Solution.** Log in and re-issue the request.

### 6.16 Error: `Remote Browser not found`

**Cause.** A Real Browser monitor references a remote Chromium endpoint that was deleted.
**Solution.** Re-add or remove the remote browser under **Settings → Remote Browsers**.

### 6.17 Error: `proxy not found`

**Cause.** A monitor references a proxy that was deleted.
**Solution.** Re-assign a proxy under monitor edit, or set **Proxy** to "None".

### 6.18 Error: `Invalid ping value. Must be between 0 and X ms.`

**Cause.** A Push monitor received a ping value outside the allowed range.
**Solution.** Normalize pings to integers within the allowed range (0 to the configured maximum).

### 6.19 Error: `Dead loop occurred in parseCertificateInfo`

**Cause.** A pathological certificate chain caused the parser to loop.
**Solution.** Check the target site with `openssl s_client -connect host:443 -showcerts` to confirm chain sanity. Report the cert to the maintainers if it is valid but unparseable.

### 6.20 Web UI shows a spinner forever (never loads)

**Cause.** WebSocket handshake is blocked (reverse proxy missing `Upgrade` headers), or the WebSocket origin check is failing.
**Solution.** Configure your reverse proxy to forward `Upgrade` and `Connection: upgrade` headers. If you are on a non-standard origin for development, set `UPTIME_KUMA_WS_ORIGIN_CHECK=bypass` (do not use in production).

### 6.21 Monitor shows up when TLS is actually broken

**Cause.** Some monitors report **up** on successful TCP even when TLS fails (issue #7265). This affects older 2.x builds.
**Solution.** Update to the latest 2.x image.

### 6.22 Cannot host under a subdirectory (e.g., `/uptimekuma`)

**Cause.** Limited subpath support — the frontend assumes it runs at root.
**Solution.** Host on a subdomain (`kuma.example.com`) instead of a subpath. Issue #7279 tracks this limitation.

### 6.23 Error: `Chromium not found`

**Cause.** Real Browser monitor cannot find a Chromium executable.
**Solution.** Either configure a remote browser endpoint under **Settings → Remote Browsers**, or set `UPTIME_KUMA_ALLOW_ALL_CHROME_EXEC=1` and ensure Chrome/Chromium is installed on the host.

### 6.24 Error: `The token is invalid due to password change or old token`

**Cause.** Your JWT session token was invalidated because the admin password was changed, or the token expired.
**Solution.** Log in again. This is expected behavior after a password change.

### 6.25 Ping monitor fails with small packet sizes

**Cause.** Ping fails if you choose a packet size below 16 bytes (issue #3574).
**Solution.** Use a packet size of 16 bytes or larger.

### 6.26 Notification timeout freezes the monitor

**Cause.** A slow notification provider blocks the heartbeat cycle (issue #4058).
**Solution.** Switch to async-friendly notification channels (Webhook, Ntfy, Gotify) instead of synchronous providers. Or reduce the notification timeout if the provider supports it.

### 6.27 MQTT monitor does not accept `mqtts://` URLs

**Cause.** The MQTT monitor parser rejects `mqtts://` protocol URLs (issue #7286).
**Solution.** Use `mqtt://` with the TLS port, or configure a proxy.

### 6.28 DB migration fails on `convert-float-precision`

**Cause.** The database migration `2026-01-10-0000-convert-float-precision.js` fails due to an interrupted previous migration attempt (issue #6920).
**Solution.** Check if `SET_MIGRATE_AGGREGATE_TABLE_TO_TRUE` environment variable helps. If the migration was interrupted, the error `Aggregate table migration is already in progress` may appear. Restore from backup and retry.

### 6.29 Error: `Incorrect current password`

**Cause.** The password you entered when changing your password does not match.
**Solution.** Enter the correct current password. If forgotten, use `npm run reset-password` from the host.

### 6.30 Error: `Invalid timezone:`

**Cause.** An invalid timezone string was provided.
**Solution.** Use a valid IANA timezone (e.g., `America/New_York`, `Europe/London`, `Asia/Tokyo`).

### 6.31 Error: `slug is not found`

**Cause.** A status page operation references a slug that does not exist.
**Solution.** Verify the status page slug in your URL or API call.

### 6.32 Error: `Only allowed PNG logo.`

**Cause.** You tried to upload a non-PNG file as a status page logo.
**Solution.** Convert your logo to PNG format before uploading.

### 6.33 Error: `Notification type is not supported`

**Cause.** The notification configuration references a provider type that is not registered.
**Solution.** Re-create the notification using a valid provider from the dropdown.

### 6.34 Error: `Invalid url protocol, only http and https are allowed.`

**Cause.** A Real Browser monitor was given a URL with a non-HTTP protocol.
**Solution.** Use `http://` or `https://` URLs only for Real Browser monitors.

### 6.35 Error: `Monitor not found or not active.`

**Cause.** A push heartbeat was sent for a monitor that does not exist or is paused.
**Solution.** Verify the push token and ensure the monitor is active.

### 6.36 Error: `Unknown Monitor Type`

**Cause.** A monitor has a type that is not registered in the system. This can happen after downgrading from a newer version.
**Solution.** Edit the monitor and set a valid type, or delete and re-create it.

### 6.37 Error: `Steam API Key not found`

**Cause.** A Steam Game Server monitor requires a Steam API key that is not configured.
**Solution.** Add your Steam API key in the monitor settings.

### 6.38 Error: `Interval cannot be less than X seconds`

**Cause.** The heartbeat interval or retry interval is below the minimum (20 seconds for heartbeat).
**Solution.** Increase the interval to at least the minimum.

### 6.39 Rate limiting: `Too frequently, try again later.`

**Cause.** You exceeded a rate limit.
**Solution.** Wait and retry. Rate limits:

| Scope | Limit |
|-------|-------|
| Login attempts | 20 per minute |
| 2FA submissions | 30 per minute |
| API (badges, push, etc.) | 60 per minute |

### 6.40 Error: `Invalid JSON in database query`

**Cause.** A monitor's JSON configuration field (headers, conditions, accepted status codes, etc.) contains invalid JSON.
**Solution.** Validate the JSON syntax. Common issues: trailing commas, unquoted keys, single quotes instead of double quotes.

---

## 7. FAQ

**Q: What ports does Uptime Kuma use?**
Only `3001/tcp` by default. Override with `UPTIME_KUMA_PORT`, the `PORT` env var, or `--port`.

**Q: Where is my data stored?**
`./data/` inside the working directory (Node.js) or `/app/data/` inside the container. SQLite lives at `./data/kuma.db`; MariaDB/MySQL data is on the external database server.

**Q: What is the minimum heartbeat interval?**
20 seconds. Shorter intervals would overload both Uptime Kuma and the monitoring target.

**Q: What is the maximum heartbeat interval?**
Defined by `MAX_INTERVAL_SECOND` in the source. For most monitor types there is a generous upper bound. Push monitors have a feature request for 30+ day intervals (issue #7264).

**Q: Can I monitor more than 1000 services?**
Yes, but switch the database to MariaDB or MySQL, raise `UPTIME_KUMA_DB_POOL_MAX_CONNECTIONS`, and give the host enough RAM. Each monitor is a small timer + crontab entry.

**Q: Does Uptime Kuma support multi-tenant / teams?**
Not officially. Uptime Kuma is designed as a single-admin tool. Use reverse-proxy auth if you need to share view-only access.

**Q: Is there a REST API to create monitors?**
A public REST API is tracked under feature request #118. Today, read-only badges and push endpoints are exposed as HTTP. Most CRUD operations happen over the Socket.IO channel (not documented as a public API).

**Q: How do I back up my data?**
Stop Uptime Kuma, copy `./data/` somewhere safe, start again. For MariaDB/MySQL use `mysqldump`. Automatic periodic backups are on the roadmap (issue #477).

**Q: How do I update Uptime Kuma?**
Docker: `docker pull louislam/uptime-kuma:2 && docker compose down && docker compose up -d`. Node.js: `git pull && npm run setup && pm2 restart uptime-kuma`. Always back up `./data/` first.

**Q: Can I use my own TLS certificate?**
Yes. Set `UPTIME_KUMA_SSL_KEY` and `UPTIME_KUMA_SSL_CERT`. Both must be set to enable HTTPS — partial config runs as HTTP. Optionally add `UPTIME_KUMA_SSL_KEY_PASSPHRASE` for encrypted keys.

**Q: Does it work behind Cloudflare?**
Yes. It also supports Cloudflared tunnels: provide `UPTIME_KUMA_CLOUDFLARED_TOKEN` to start a tunnel automatically on boot.

**Q: Can Uptime Kuma monitor itself?**
The container includes a `HEALTHCHECK` (Go binary at `extra/healthcheck`) and a Prometheus `/metrics` endpoint. For true external monitoring, use a second Uptime Kuma instance or a different monitoring service.

**Q: How do I change the data directory?**
Set `DATA_DIR` (e.g., `DATA_DIR=/var/kuma/`) or pass `--data-dir`. The path must end with `/`.

**Q: Does Uptime Kuma send my data anywhere?**
No telemetry. Notifications go only to the endpoints you configure. Version checks hit GitHub (disable via `TEST_CHECK_VERSION=0`).

**Q: Why is a monitor still showing "up" when my site is down?**
Check the monitor type matches the failure you care about. A TCP monitor stays green if the port accepts a connection even when the application returns HTTP 500. Use an HTTP monitor with **Accepted Status Codes** for full-stack checks.

**Q: Can I export my monitors?**
Yes. **Settings → Backup → Export**. A JSON file is produced. Re-import via the same page.

**Q: What happens to history when I delete a monitor?**
It is permanently deleted. There is no soft-delete. Export the data first if you need to keep it.

**Q: Does Chinese / non-ASCII input work everywhere?**
Yes. Uptime Kuma is fully Unicode-aware in names, descriptions, and notifications.

**Q: How many notification providers are supported?**
93 notification providers ship with version 2.2.1. See the full catalog in the Notification Providers section below.

**Q: Can I send test notifications?**
Yes. Every notification channel has a **Test** button in the setup dialog. It sends a sample alert using the current configuration.

**Q: Can I apply a notification to all monitors at once?**
Yes. When creating or editing a notification channel, check **Apply on all existing monitors**.

**Q: What databases can I monitor?**
MySQL/MariaDB, PostgreSQL, MongoDB, Microsoft SQL Server, Oracle DB, and Redis.

**Q: Can I monitor a Kafka cluster?**
Yes, via the **Kafka Producer** monitor type. Configure broker addresses and optional SASL authentication as valid JSON.

**Q: What game servers can I monitor?**
Any server supported by the GameDig library (Minecraft, Valheim, Counter-Strike, ARK, Team Fortress 2, and hundreds more). For Steam servers specifically, use the Steam Game Server type.

**Q: Can I monitor a RADIUS server?**
Yes, via the built-in **RADIUS** monitor type. Enter the RADIUS server address, shared secret, and test credentials.

**Q: How do I set up 2FA?**
Settings → Security → Enable 2FA. Scan the TOTP QR code with any TOTP app. Each token is single-use within its 30-second window.

**Q: How do I reset 2FA if I lose my authenticator?**
From the server host: `npm run remove-2fa`. It prompts for the username.

**Q: How do I reset the admin password?**
From the server host: `npm run reset-password`. It prompts for the username and new password.

**Q: Can I disable authentication entirely?**
Yes, under **Settings → Security → Disable Auth**. Not recommended for internet-facing instances.

**Q: What is the `entryPage` setting?**
Under **Settings → General**, you choose whether the root URL (`/`) redirects to the dashboard or a specific status page.

**Q: Does Uptime Kuma support OIDC / OAuth login?**
Yes. Configure under **Settings → Security → OIDC / OAuth** with client ID, secret, discovery URL, and scopes.

**Q: Can I embed Uptime Kuma in an iframe?**
By default, `X-Frame-Options: SAMEORIGIN` prevents cross-origin embedding. Set `UPTIME_KUMA_DISABLE_FRAME_SAMEORIGIN` to allow it.

**Q: What is the `.well-known/change-password` endpoint?**
Uptime Kuma serves this endpoint per the W3C specification, allowing password managers to find the password change page.

**Q: Can I use structured JSON logging?**
Yes. Set `UPTIME_KUMA_LOG_FORMAT=json` for JSON-formatted log output.

---

## Appendices

### Appendix A: Notification provider catalog (93 providers)

All notification providers ship under `server/notification-providers/` and are registered at startup.

| Category | Providers |
|----------|-----------|
| **Team chat / messaging** | Slack, Discord, Telegram, Microsoft Teams, Mattermost, Rocket.Chat, Matrix, Google Chat, DingDing, Feishu, Kook, Line, VK, WeCom, Whapi, WAHA, Onesender, 360messenger, Nextcloud Talk, Bitrix24, Pumble, Stackfield, ZohoCliq, OneBot, OneChat, Signal, Max, Bale, YZJ, Nostr |
| **Incident management** | PagerDuty, PagerTree, Opsgenie, GoAlert, Squadcast, Splunk, SIGNL4, HeiiOnCall, FlashDuty, AlertNow, Alerta, Grafana OnCall, Jira Service Management, HaloPSA, Keep |
| **SMS gateways** | Twilio, Telnyx, ClickSend SMS, Cellsynt, SMSC, SMSEagle, SMS Manager, SMS Partner, SMS Planet, SMSIR, SevenIO, Serwer SMS, Aliyun SMS, FreeMobile, GTX Messaging, Octopush, PromoSMS, CallMeBot, 46elks |
| **Email** | SMTP (built-in), SendGrid, Resend, Brevo |
| **Push / notification services** | Ntfy, Gotify, Pushover, Pushbullet, Pushy, PushPlus, PushDeer, Techulus Push, Bark, Spug Push, WPush, ServerChan, Apprise |
| **Generic / other** | Webhook, Web Push (browser), Home Assistant, Notifery, Teltonika, Evolution, Fluxer, Threema, Google Sheets, LunaSea, Gorush |

### Appendix B: Helper npm scripts

| Command | What it does |
|---------|--------------|
| `npm run setup` | Checkout tagged release, install production dependencies, download prebuilt frontend. |
| `node server/server.js` or `npm start` | Start the server. |
| `npm run dev` | Start frontend (Vite) + backend concurrently for development. |
| `npm run reset-password` | Reset the admin password interactively. |
| `npm run remove-2fa` | Disable 2FA for a user interactively. |
| `npm run simple-dns-server` | Local test DNS server for DNS monitor development. |
| `npm run simple-mqtt-server` | Local test MQTT broker for MQTT monitor development. |
| `npm run mark-as-nightly` | Flag the running image as a nightly build. |

### Appendix C: Health check

The Docker image includes `extra/healthcheck` (a Go binary) and `extra/healthcheck.js` (a Node.js fallback). Docker runs the health check every 60 seconds with:

- Timeout: 30 seconds
- Retries: 5
- Start period: 180 seconds

The health check makes an HTTP(S) request to the local server, respecting the same SSL configuration environment variables.

### Appendix D: Prometheus metrics

`GET /metrics` returns Prometheus-format metrics (exposed via `prom-client` + `prometheus-api-metrics`). This includes default Node.js runtime metrics (memory, event loop, GC) plus per-monitor heartbeat data.

The endpoint requires basic auth using the admin credentials.

### Appendix E: External resources

- Official wiki: `https://github.com/louislam/uptime-kuma/wiki`
- Milestones and roadmap: `https://github.com/louislam/uptime-kuma/milestones`
- Subreddit: `https://www.reddit.com/r/UptimeKuma/`
- Translations (Weblate): `https://weblate.kuma.pet/`

---

_Generated May 2026 from louislam/uptime-kuma at 43b143c. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
