louislam/uptime-kuma · error · Error
Aggregate table migration is already in progress
Error message
Aggregate table migration is already in progress
What it means
migrateAggregateTable() reads the Settings key 'migrateAggregateTableState'. The value 'migrating' indicates a previous run started the aggregate-table migration but never set it to 'migrated', which happens when the process was killed mid-migration. Rather than risk two concurrent migrations corrupting aggregate data, Uptime Kuma refuses to start. The warning log just above ('…or it was interrupted') tells you the same thing.
Source
Thrown at server/database.js:875
// Add a setting for 2.0.0-dev users to skip this migration
if (process.env.SET_MIGRATE_AGGREGATE_TABLE_TO_TRUE === "1") {
log.warn(
"db",
"SET_MIGRATE_AGGREGATE_TABLE_TO_TRUE is set to 1, skipping aggregate table migration forever (for 2.0.0-dev users)"
);
await Settings.set("migrateAggregateTableState", "migrated");
}
let migrateState = await Settings.get("migrateAggregateTableState");
// Skip if already migrated
// If it is migrating, it possibly means the migration was interrupted, or the migration is in progress
if (migrateState === "migrated") {
log.debug("db", "Migrated aggregate table already, skip");
return;
} else if (migrateState === "migrating") {
log.warn("db", "Aggregate table migration is already in progress, or it was interrupted");
throw new Error("Aggregate table migration is already in progress");
}
/**
* Start migration server for displaying the migration status
* @type {SimpleMigrationServer}
*/
let migrationServer;
let msg;
if (port) {
migrationServer = new SimpleMigrationServer();
await migrationServer.start(port, hostname);
}
log.info("db", "Migrating Aggregate Table");
log.info("db", "Getting list of unique monitors");
View on GitHub (pinned to 6b5ea01557)
Solutions
- Simply start the server again — if the prior migration actually completed but failed to flip the flag, a clean retry will set 'migrated'.
- If it genuinely crashed mid-migration and the data is intact, the safest recovery is to set the flag manually: run the SQLite shell (or MariaDB client) and UPDATE the setting, e.g. `UPDATE setting SET value='migrated' WHERE key='migrateAggregateTableState';`, after confirming the aggregate tables are fully populated.
- For 2.0.0-dev users who want to skip the migration entirely, set env `SET_MIGRATE_AGGREGATE_TABLE_TO_TRUE=1` on the next start (see database.js:858).
- If the migration keeps failing, check disk space and the migration status server (port/hostname args to migrateAggregateTable) for the underlying error.
Example fix
# before — stuck in 'migrating' after a crash # (server refuses to boot) # after — reset the flag in SQLite and restart sqlite3 ./data/kuma.db "UPDATE setting SET value='migrated' WHERE key='migrateAggregateTableState';" npm run start
Defensive patterns
Strategy: fallback
Validate before calling
// Pre-flight: detect the stuck 'migrating' state before boot
const { Database } = require("./server/database");
const { Settings } = require("./server/settings");
async function migrationIsStuck() {
await Database.connect(false, false, true);
const s = await Settings.get("migrateAggregateTableState");
return s === "migrating";
} Try / catch
try {
await Database.migrateAggregateTable(port, hostname);
} catch (e) {
if (/already in progress/.test(e.message)) {
// either retry once (the prior run may have finished) or, if you are certain
// the data is consistent, set migrateAggregateTableState=migrated and restart
log.error("startup", e.message);
process.exit(1);
}
throw e;
} Prevention
- Avoid hard-killing the process during a major version upgrade; let it shut down cleanly.
- Monitor disk and memory during the 1.x -> 2.x migration so the OOM killer does not interrupt it.
- Keep the SET_MIGRATE_AGGREGATE_TABLE_TO_TRUE=1 escape hatch documented for dev instances.
When it happens
Trigger: The server was SIGKILLed, OOM-killed, or lost power during the startup aggregate-table migration (introduced for the 2.x data model). On next boot the setting still reads 'migrating' and boot aborts.
Common situations: Hard restarts during an upgrade from 1.x to 2.x; containers killed past their grace period; low-memory hosts where the OOM killer terminates node mid-migration.
Related errors
- Invalid db-config.json, type must be a string
- Unknown Database type: ${dbConfig.type}
- Both ${envName} and ${envName}_FILE are set. Please use only
- Failed to read ${envName}_FILE at ${fileValue}: ${err.messag
- Embedded Mariadb supports only 'node' or 'root' user, but th
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/718c84473c85487b.
Report an issue: GitHub.