The Great Uptime Kuma Upgrade: A Tale of Stuck Migrations and .io Domain Betrayal
tl;dr: Upgraded Uptime Kuma from v1 to v2, got stuck in a migration bootloop, fixed it with some SQLite surgery, then upgraded Portainer because apparently I hate stability.
Act I: “Wait, What Version Am I On?”
Me: “I should update Uptime Kuma.”
UI: “You’re on v1.23.17”
Logs after restarting: “Uptime Kuma Version: 2.2.1”
Me: “…wat”
Turns out I’d already upgraded at some point but the UI was living in the past. Cool. Cool cool cool.
Act II: The Bootloop of Doom
Tried to start the container. Got this instead:
[DB] WARN: Aggregate table migration is already in progress, or it was interrupted
[DB] ERROR: Database migration failed
[SERVER] ERROR: Failed to prepare your database
Repeat ad infinitum
Classic “migration started, never finished, now refuses to do anything” situation. The container was crashing faster than my confidence.
Act III: SQLite to the Rescue
Stopped the container (well, it stopped itself repeatedly, I just made it stay stopped), popped into the database:
bash
cd /data/compose/14/data
sqlite3 kuma.db
Found the culprit:
sql
SELECT * FROM setting WHERE key = 'migrateAggregateTableState';
-- Returns: "migrating"
But wait! Did the migration actually fail, or did it just forget to update the flag? Time for some forensics:
sql
SELECT COUNT(*) FROM stat_minutely; -- 80 rows
SELECT COUNT(*) FROM stat_hourly; -- 54 rows
SELECT COUNT(*) FROM stat_daily; -- 73 rows
The migration had completed – it just failed to clear its own flag. Like finishing a marathon and forgetting to cross the finish line.
The fix:
sql
UPDATE setting SET value = '"migrated"' WHERE key = 'migrateAggregateTableState';
```
Restarted the container. No more bootloop. Victory!
## Act IV: Domain Expiry Monitoring (LOL)
Got all excited about v2's new domain expiry monitoring feature. You know, the thing that warns you before your domain registration expires.
Checked the logs:
```
[DOMAIN_EXPIRY] WARN: Domain expiry unsupported for '.io' because its RDAP endpoint
is not listed in the IANA database.
My primary domain is satchnet.io.
The feature doesn’t work for .io domains.
😐
Act V: Portainer Upgrade (Because Why Not)
Having successfully upgraded one thing, I decided to tempt fate and upgrade Portainer too.
This one was anticlimactic:
bash
docker pull portainer/portainer-ce:lts
docker stop portainer && docker rm portainer
docker run -d ... # (same flags as before)
Migrated cleanly from 2.33.7 to 2.39.0. No drama. No stuck migrations. No existential database crises.
Honestly kind of disappointing after the Uptime Kuma adventure.
Lessons Learned
- LXC snapshots before upgrades – always, every time, no exceptions
- Database migrations can lie – if it says “in progress,” check if it actually finished
- Not all upgrades are created equal – some are smooth (Portainer), some require SQLite wizardry (Uptime Kuma)
.iodomains are second-class citizens in the domain expiry monitoring world- “If it ain’t broke, don’t fix it” is good advice I will continue to ignore
The End
Everything works now. Uptime Kuma is on v2.2.1, Portainer is on 2.39.0, and I have exactly zero domain expiry monitoring for my .io domains.
10/10 would troubleshoot stuck migrations again.
P.S. – Huge thanks to Claude for the SQLite forensics. Without the “check if the tables actually have data” step, I’d probably still be in that bootloop.