Skip to content

Instantly share code, notes, and snippets.

@jcpowermac
Created May 24, 2026 16:24
Show Gist options
  • Select an option

  • Save jcpowermac/d029475c52762b4805a19e54f660f37c to your computer and use it in GitHub Desktop.

Select an option

Save jcpowermac/d029475c52762b4805a19e54f660f37c to your computer and use it in GitHub Desktop.
pangolin 1.18 upgrade sqlite issue and fix via cursor

cursor determined the fix

Pangolin 1.18 upgrade: SqliteError: no such column: resources.health

A troubleshooting guide for Pangolin upgrades from 1.17.x → 1.18.x when the SQLite database schema is out of sync with the running application.

Tested fix path: seed versionMigrations with 1.17.0, then re-run migrations.


Symptoms

After upgrading Pangolin to 1.18.x (e.g. 1.18.4), the service may fail to start with errors like:

SqliteError: no such column: resources.health

Or, after partial manual fixes:

SqliteError: no such column: "networkId"

Migration logs may misleadingly show success:

Starting migrations from version 1.18.4
Migrations to run:
All migrations completed successfully

…while the database is still on the 1.17 schema.


Root cause

Pangolin tracks applied migrations in the versionMigrations SQLite table. The migration runner uses the highest version in that table as the starting point:

  • If versionMigrations is empty, it defaults to the current app version (e.g. 1.18.4).
  • Nothing runs because no migration version is greater than 1.18.4.
  • The app code expects 1.18 columns (resources.health, sites.networkId, networks table, etc.) that were never created.

This commonly happens when:

  1. versionMigrations was wiped (e.g. Proxmox community-scripts update logic deletes all rows when statusHistory is missing).
  2. A partial upgrade left migration records at 1.18.x without completing the 1.18.0 schema changes.
  3. Manual SQL patches (adding individual columns) bypass the full 1.18.0 migration — each missing column causes the next error.

Do not fix this by adding columns one at a time. The 1.18.0 migration is large (new tables, recreated siteResources / targetHealthCheck, data migration, status history seeding).


Who this affects

  • Proxmox LXC installs via community-scripts/ProxmoxVE (/opt/pangolin, systemctl pangolin)
  • Docker installs (config/db/db.sqlite mounted into the container)
  • Any local SQLite install using Pangolin's migration runner (dist/migrations.mjs)

Quick diagnosis

Adjust paths for your install:

Install type Database path
Proxmox LXC /opt/pangolin/config/db/db.sqlite
Docker ./config/db/db.sqlite (or your volume mount)
DB="/opt/pangolin/config/db/db.sqlite"   # change if needed

echo "=== versionMigrations ==="
sqlite3 "$DB" "SELECT version FROM versionMigrations ORDER BY version;"

echo "=== 1.18 columns ==="
sqlite3 "$DB" "PRAGMA table_info(resources);" | grep -E 'health|wildcard' || echo "MISSING: resources.health"
sqlite3 "$DB" "PRAGMA table_info(sites);" | grep networkId || echo "MISSING: sites.networkId"

echo "=== 1.18 tables ==="
sqlite3 "$DB" "SELECT name FROM sqlite_master WHERE type='table' AND name IN ('networks','statusHistory','alertRules');"

Broken state looks like:

  • versionMigrations is empty or only has 1.18.x rows while columns/tables above are missing.
  • Logs show Starting migrations from version 1.18.4 with an empty Migrations to run: line.

Fix (recommended): seed 1.17.0 and re-run migrations

Proxmox LXC (systemd)

systemctl stop pangolin gerbil

DB="/opt/pangolin/config/db/db.sqlite"
cp "$DB" "/opt/pangolin/config/db/db.sqlite.backup-$(date +%Y%m%d-%H%M%S)"

# Remove any false 1.18 migration records
sqlite3 "$DB" "DELETE FROM versionMigrations WHERE version IN ('1.18.0','1.18.3','1.18.4');"

# If the table is empty, tell the migrator we are at 1.17.0
COUNT=$(sqlite3 "$DB" "SELECT COUNT(*) FROM versionMigrations;")
if [ "$COUNT" -eq 0 ]; then
  sqlite3 "$DB" "INSERT INTO versionMigrations (version, executedAt) VALUES ('1.17.0', cast(strftime('%s','now') as integer) * 1000);"
fi

# Run migrations manually and watch output
cd /opt/pangolin
ENVIRONMENT=prod node dist/migrations.mjs

Expected output:

Starting migrations from version 1.17.0
Migrations to run: 1.18.0, 1.18.3, 1.18.4
Running migration 1.18.0
...
Recomputed health for N resource(s)
Successfully completed migration 1.18.0
...
All migrations completed successfully
# Verify schema
sqlite3 "$DB" "PRAGMA table_info(resources);" | grep health
sqlite3 "$DB" "PRAGMA table_info(sites);" | grep networkId
sqlite3 "$DB" "SELECT version FROM versionMigrations ORDER BY version;"

systemctl start pangolin gerbil
journalctl -u pangolin -n 30 --no-pager
curl -sf http://localhost:3001/api/v1/   # should return {"message":"Healthy"}

Docker

docker compose stop pangolin

DB="./config/db/db.sqlite"
cp "$DB" "./config/db/db.sqlite.backup-$(date +%Y%m%d-%H%M%S)"

sqlite3 "$DB" "DELETE FROM versionMigrations WHERE version IN ('1.18.0','1.18.3','1.18.4');"
COUNT=$(sqlite3 "$DB" "SELECT COUNT(*) FROM versionMigrations;")
if [ "$COUNT" -eq 0 ]; then
  sqlite3 "$DB" "INSERT INTO versionMigrations (version, executedAt) VALUES ('1.17.0', cast(strftime('%s','now') as integer) * 1000);"
fi

docker compose run --rm pangolin node dist/migrations.mjs
# Or exec into the container with ENVIRONMENT=prod if your image supports it

docker compose up -d pangolin
docker logs pangolin 2>&1 | tail -30

Alternative: restore a pre-1.18 backup

If migrations fail with "table already exists" or "duplicate column", the database is in a mixed state. Restore instead of patching.

Pangolin auto-backups before migrations:

config/db/backups/db_YYYY-MM-DD_*.sqlite

Proxmox update script may also create:

/opt/pangolin/config/db/db.sqlite.pre-1.18.4-*.bak
systemctl stop pangolin gerbil   # or docker compose stop pangolin

cp config/db/backups/db_<pre-1.18-timestamp>.sqlite config/db/db.sqlite

cd /opt/pangolin && ENVIRONMENT=prod node dist/migrations.mjs
systemctl start pangolin gerbil

What NOT to do

Don't Why
DELETE FROM versionMigrations; without re-inserting 1.17.0 Causes migrations to skip entirely
Manually ALTER TABLE resources ADD health ... only Next error will be networkId, then more — 1.18.0 changes ~20+ schema items
Assume "All migrations completed successfully" means OK Empty Migrations to run: with start version 1.18.4 means nothing ran
Upgrade from 1.18 RC → 1.18 release on same DB Not supported; restore 1.17 backup first (issue #2925)

Verification checklist

  • versionMigrations contains 1.17.0, 1.18.0, 1.18.3, 1.18.4
  • resources.health column exists
  • sites.networkId column exists
  • networks and statusHistory tables exist
  • Pangolin starts without SqliteError in logs
  • API health check returns {"message":"Healthy"} (internal port 3001)
  • Dashboard loads; resource health checks display in UI

Related issues


One-liner summary

Empty versionMigrations + Pangolin 1.18 app = skipped migrations. Insert 1.17.0, run node dist/migrations.mjs, verify resources.health exists, restart start the service.


Contributions welcome — if you hit an edge case, please note your install method, Pangolin version, and migration log output in a comment or PR. ➜ ~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment