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

  1. LXC snapshots before upgrades – always, every time, no exceptions
  2. Database migrations can lie – if it says “in progress,” check if it actually finished
  3. Not all upgrades are created equal – some are smooth (Portainer), some require SQLite wizardry (Uptime Kuma)
  4. .io domains are second-class citizens in the domain expiry monitoring world
  5. “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.

Add a Comment

Your email address will not be published. Required fields are marked *