Upgrade, rollback and repair
MAIA Plus is updated only as a complete signed package, and only through the maintenance utility — MAIA-MAINTENANCE.exe on Windows, maia-maintenance-linux on Linux. There is no separate updater service, and no supported way to replace a live binary, the WebUI build or a migration file by hand. This page describes one update cycle, the Windows and Linux form of every command, and what happens when it fails.
The update lifecycle
Section titled “The update lifecycle”verify signature → preflight (read-only) → pg_dump when migrations are pending→ atomic switch current/previous → restart service → health gate→ success, or automatic rollbackEach step exists for a reason:
| Step | Why it cannot be skipped |
|---|---|
| Signature check | Proves the package is the one that was built and published |
| Preflight | Validates service configuration, PostgreSQL tools and connectivity, the migration ledger, the backup directory and the health endpoint without touching anything |
Verified pg_dump | Only runs when pendingCount > 0; a database change without a dump cannot be rolled back |
| Atomic switch | current becomes the new payload, the old one moves to previous; nothing is edited in place |
| Health gate | http://127.0.0.1:3000/api/v1/status must return 200 |
| State file | state/maintenance-update.json records what happened, for the next person |
Two platform profiles
Section titled “Two platform profiles”The procedure is identical; the paths, the shell and the service manager are not.
| Windows | Linux | |
|---|---|---|
| Maintenance utility | MAIA-MAINTENANCE.exe | maia-maintenance-linux |
| Install root | The directory chosen at install, typically C:\MAIA | /opt/maia |
| Managed service | NSSM service, default name MAIA; a native sc.exe service is also detected | maia.service (systemd) |
| Driver selection | --service-driver auto detects NSSM versus native | --service-driver auto detects systemd |
| Elevation | PowerShell started with Run as administrator | sudo |
| Backup directory | D:\MAIA-Backups\<date> | /var/backups/maia/<date> |
| Guided scripts in the package | install.bat, update.bat | update.sh |
--backup-dir must be a persistent directory with free space — not the install root, not a temporary folder. --service-driver auto is the right default; name the driver explicitly only when auto-detection picks the wrong one.
Before you start
Section titled “Before you start”- Maintenance window —
--confirmstops the service, so the restart is a planned outage. - Elevated shell — the update starts and stops a service.
- Install root and service name exactly as the running installation uses them. A wrong service name blocks the preflight rather than guessing.
- Durable backup directory with free space, outside the install root.
pg_dumpandpg_restore— assume they are not onPATH. Pass absolute paths with--pg-dumpand--pg-restore; on Windows this is the normal case, not the exception.- The new signed ZIP extracted outside the live root, into a fresh directory.
Run the update
Section titled “Run the update”1. Verify the package
Section titled “1. Verify the package”cd D:\MAIA-Releases\1.1.1.\MAIA-MAINTENANCE.exe check --package .cd /srv/maia-releases/<version>/update./maia-maintenance-linux check --package .check reads the manifest, the signature and the payload checksums. It prints Verified release <id>. and changes nothing; a failure here means the archive is incomplete or was modified, so re-download it instead of continuing.
2. Run the read-only preflight
Section titled “2. Run the read-only preflight”It ends in READY TO UPDATE or UPDATE BLOCKED with a reason.
.\MAIA-MAINTENANCE.exe update ` --package . ` --install-root C:\MAIA ` --service MAIA ` --service-driver auto ` --backup-dir D:\MAIA-Backups\2026-11-03sudo ./maia-maintenance-linux update \ --package . \ --install-root /opt/maia \ --service maia.service \ --service-driver auto \ --backup-dir /var/backups/maia/<date>The preflight verifies the service configuration, the PostgreSQL client tools, database connectivity, the migration ledger, the backup directory and the health endpoint. Nothing is written: no file, no database row, no service state, no backup.
An installation that is not managed as a service is updated with --no-service; the tool then refuses to verify the process is down, so a confirmed run additionally requires --manual-service-acknowledgement.
Pass the PostgreSQL tool paths
Section titled “Pass the PostgreSQL tool paths”The dump is what makes a rollback possible, so the preflight refuses to continue when it cannot find pg_dump. Do not rely on PATH. A Windows host almost never has PostgreSQL client tools on it, and a working installation is not the same thing as a discoverable one — pass both paths explicitly in the preflight and in the confirmed run:
# All-in-One installer: PostgreSQL lives in the prerequisites root.\MAIA-MAINTENANCE.exe update ` --package . ` --install-root C:\MAIA ` --service MAIA ` --backup-dir D:\MAIA-Backups\2026-11-03 ` --pg-dump "C:\MAIA-Prerequisites\pgsql\bin\pg_dump.exe" ` --pg-restore "C:\MAIA-Prerequisites\pgsql\bin\pg_restore.exe"# Standalone PostgreSQL 18 installed with its own installer.\MAIA-MAINTENANCE.exe update ` --package . ` --install-root C:\MAIA ` --service MAIA ` --backup-dir D:\MAIA-Backups\2026-11-03 ` --pg-dump "C:\Program Files\PostgreSQL\18\bin\pg_dump.exe" ` --pg-restore "C:\Program Files\PostgreSQL\18\bin\pg_restore.exe"# Debian/Ubuntu packages: /usr/bin is normally on PATH, so an explicit path is optionalsudo ./maia-maintenance-linux update \ --package . \ --install-root /opt/maia \ --service maia.service \ --backup-dir /var/backups/maia/<date> \ --pg-dump /usr/bin/pg_dump \ --pg-restore /usr/bin/pg_restoreUse binaries of at least the server’s major version. pg_dump aborts when the server is newer than itself, and pg_restore refuses a dump format it does not recognise — so an old client copied from another host turns a valid backup into a blocked preflight. When the database runs in a container or on another host, the tools still run on the MAIA host: install a matching client there instead of loosening the check.
3. Confirm the update
Section titled “3. Confirm the update”Only when the preflight says READY, confirm. --confirm performs, in order: the verified dump (only when migrations are pending), the atomic switch, the service registration update, the restart, and the health gate.
.\MAIA-MAINTENANCE.exe update --confirm ` --package . ` --install-root C:\MAIA ` --service MAIA ` --service-driver auto ` --backup-dir D:\MAIA-Backups\2026-11-03sudo ./maia-maintenance-linux update --confirm \ --package . --install-root /opt/maia --service maia.service \ --service-driver auto --backup-dir /var/backups/maia/<date>Guided update on Windows
Section titled “Guided update on Windows”The package also ships update.bat for operators who prefer not to assemble the command line. Run it with Run as administrator: it asks for the install root and the service name, runs the read-only preflight, and applies the update only after you type UPDATE. With --no-service it asks only for that typed confirmation and supplies --manual-service-acknowledgement for you — the tool cannot verify the process is down, so the acknowledgement is the operator’s, not the script’s. install.bat follows the same shape for a first installation, ending at the WebUI Setup Wizard.
On Linux, update.sh wraps the same call with --confirm: it requires root, --install-root and either --service <name> or --no-service, and asks for UPDATE — plus MANUAL when the service is not managed.
The scripts are wrappers, not a different mechanism — they call the same MAIA-MAINTENANCE.exe update shown above, so a blocked preflight blocks the script too.
4. Read the result
Section titled “4. Read the result”The update is complete only when the health gate passes and the state file records COMMITTED. Every other ending requires interpretation.
stage | Meaning | What it proves |
|---|---|---|
COMMITTED | Update finished and the health gate passed | The new build is serving |
FAILED | The update failed; automatic rollback is starting | Nothing yet — rollback has not been evaluated |
ROLLED_BACK | Automatic rollback completed without collected failures | The previous build is serving again |
INTERRUPTED | The process died, or the recorded state was unreadable | Unknown — inspect current/, previous/ and the dump |
recovery_required (legacy state file) | At least one rollback step failed | Manual recovery with the recorded backup — see When it fails |
FAILED is not a verdict on rollback, and ROLLED_BACK is not a verdict on the data. Rollback restores the database only when pending migrations were applied, and a failed restore is collected as a rollback failure — in which case the run ends as recovery_required rather than ROLLED_BACK.
The health gate reads /api/v1/status, which answers whenever the process is up; it proves the service started, not that every feature is enabled. Confirm the version actually serving, and whether the runtime suspended itself, at the administrator status endpoint:
Invoke-RestMethod http://127.0.0.1:3000/api/v1/admin/system/statuscurl -s -H "Cookie: maia_webui_token=<session>" \ http://127.0.0.1:3000/api/v1/admin/system/status \ | jq '{version, buildDate, suspension}'The response carries version, buildDate, schemaVersion and the current suspension state; the same values are shown in Administration → System status. Keep the terminal output, the state file and the dump path in every case.
Windows service management
Section titled “Windows service management”Windows installations add three service operations that have no Linux counterpart, because the service is created and repaired by the same utility.
| Command | What it does | What it never does |
|---|---|---|
bootstrap-service --install-root <path> [--service MAIA] [--setup] | Creates and starts an NSSM service for an installation that was deployed with --no-service | Replace an existing service |
repair-service --install-root <path> [--service MAIA] [--confirm] | Reconciles Application, AppDirectory and the stdout/stderr log files with the managed layout; without --confirm it only prints the plan | Modify unmanaged NSSM settings such as the account or the recovery policy |
doctor [--install-root <path>] [--service MAIA] [--json] | Read-only report of layout, service state, database and health | Change anything |
.\MAIA-MAINTENANCE.exe doctor --install-root C:\MAIA --service MAIA.\MAIA-MAINTENANCE.exe repair-service --install-root C:\MAIA --service MAIA --confirmTwo details decide whether a Windows update can proceed:
- The service name must match.
--service MAIAis the default the installer creates; a renamed service has to be named in every command, or the preflight blocks. - NSSM must be resolvable. The package bundles
nssm.exe; an existing NSSM somewhere else is named with--nssm <path>.--service-driver nssmforces NSSM handling,nativeforces asc.exe-registered service, andnoneskips service control entirely.
The Windows build ships in two variants: the standard mwtsolutions-maia-win.exe and MAIA-MAINTENANCE.exe, and the -baseline pair for CPUs without AVX2. Use the pair that matches the binary already serving; a baseline update over a standard installation is a downgrade of instruction-set assumptions, not a fresh install.
When it fails
Section titled “When it fails”Automatic rollback
Section titled “Automatic rollback”It runs when activation or the health gate fails:
- Restore the database — only if pending migrations were applied.
- Move
previousback tocurrent. - Restore the service launch settings.
- Restart the prior service.
- Write the failure to the state file.
Without pending migrations there is no dump, and previous alone is enough.
Manual recovery
Section titled “Manual recovery”After a failed attempt:
.\MAIA-MAINTENANCE.exe recover --install-root C:\MAIA --service MAIA.\MAIA-MAINTENANCE.exe recover --install-root C:\MAIA --service MAIA --restore-databasesudo ./maia-maintenance-linux recover --install-root /opt/maia --service maia.servicesudo ./maia-maintenance-linux recover --install-root /opt/maia --service maia.service --restore-databaserecover restores the journaled database, the payload and the service configuration. Do not repeat --confirm on a half-switched root: it produces a worse state than a recover.
repair is not an update
Section titled “repair is not an update”repair — also reachable as db-repair — rebuilds a candidate database from the canonical DDL, copies data on a best-effort basis, validates the candidate, and only then renames the production database to a timestamped archive. The archive is kept, not dropped — but it is a rename of the live database, so the data visible to the application is the rebuilt candidate. It requires --confirm-repair and a persistent --backup-dir, plus a DBA decision that the database is damaged or not migratable; it is not a normal upgrade step.
Rules that keep an installation recoverable
Section titled “Rules that keep an installation recoverable”- Migrations are forward-only. Editing a released
.sqlfile producesMigration ledger mismatch; the fix is a new file, not an edit. ddl.sqlmust equalsrc/db/unified_schema.sql. A divergence blocks the build, by design.- Keep
previousand the dump until the release is accepted. - Never replace a live binary or
MAIA-WEBUI/with a loose copy — on Windows the service holds the.exeopen, so a manual copy fails halfway instead of cleanly. - Signature files travel with the package —
release-manifest.jsonand.sigare part of it.
Limits and failure modes
Section titled “Limits and failure modes”| Symptom | Meaning |
|---|---|
UPDATE BLOCKED before any change | A prerequisite failed; read the reason, fix it, re-run the preflight |
Migration ledger mismatch | A released migration was modified |
| Health gate fails after switch | Rollback ran; service is on previous |
--pg-dump missing and not on PATH | Blocked, because a verified backup cannot be produced |
UPDATE BLOCKED: MAIA backend is still running under --no-service | The health endpoint answered, so the runtime is alive; stop it before a confirmed run |
MAIA_MAINTENANCE_HEALTH_URL must be an HTTP(S) loopback URL | The health override is not a local URL without credentials |
| Repeated failure on the same root | Use recover, then investigate; do not stack --confirm attempts |
Related topics
Section titled “Related topics”Installation · Windows All-in-One installer · Backup and restore · Diagnostics · Troubleshooting: connections