{"record":{"id":"718c84473c85487b","repo":"louislam/uptime-kuma","slug":"aggregate-table-migration-is-already-in-progress","errorCode":null,"errorMessage":"Aggregate table migration is already in progress","messagePattern":"Aggregate table migration is already in progress","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/database.js","lineNumber":875,"sourceCode":"        // Add a setting for 2.0.0-dev users to skip this migration\n        if (process.env.SET_MIGRATE_AGGREGATE_TABLE_TO_TRUE === \"1\") {\n            log.warn(\n                \"db\",\n                \"SET_MIGRATE_AGGREGATE_TABLE_TO_TRUE is set to 1, skipping aggregate table migration forever (for 2.0.0-dev users)\"\n            );\n            await Settings.set(\"migrateAggregateTableState\", \"migrated\");\n        }\n\n        let migrateState = await Settings.get(\"migrateAggregateTableState\");\n\n        // Skip if already migrated\n        // If it is migrating, it possibly means the migration was interrupted, or the migration is in progress\n        if (migrateState === \"migrated\") {\n            log.debug(\"db\", \"Migrated aggregate table already, skip\");\n            return;\n        } else if (migrateState === \"migrating\") {\n            log.warn(\"db\", \"Aggregate table migration is already in progress, or it was interrupted\");\n            throw new Error(\"Aggregate table migration is already in progress\");\n        }\n\n        /**\n         * Start migration server for displaying the migration status\n         * @type {SimpleMigrationServer}\n         */\n        let migrationServer;\n        let msg;\n\n        if (port) {\n            migrationServer = new SimpleMigrationServer();\n            await migrationServer.start(port, hostname);\n        }\n\n        log.info(\"db\", \"Migrating Aggregate Table\");\n\n        log.info(\"db\", \"Getting list of unique monitors\");\n","sourceCodeStart":857,"sourceCodeEnd":893,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/database.js#L857-L893","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before — stuck in 'migrating' after a crash\n# (server refuses to boot)\n\n# after — reset the flag in SQLite and restart\nsqlite3 ./data/kuma.db \"UPDATE setting SET value='migrated' WHERE key='migrateAggregateTableState';\"\nnpm run start","handlingStrategy":"fallback","validationCode":"// Pre-flight: detect the stuck 'migrating' state before boot\nconst { Database } = require(\"./server/database\");\nconst { Settings } = require(\"./server/settings\");\nasync function migrationIsStuck() {\n    await Database.connect(false, false, true);\n    const s = await Settings.get(\"migrateAggregateTableState\");\n    return s === \"migrating\";\n}","typeGuard":null,"tryCatchPattern":"try {\n    await Database.migrateAggregateTable(port, hostname);\n} catch (e) {\n    if (/already in progress/.test(e.message)) {\n        // either retry once (the prior run may have finished) or, if you are certain\n        // the data is consistent, set migrateAggregateTableState=migrated and restart\n        log.error(\"startup\", e.message);\n        process.exit(1);\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["database","migration","startup"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}