The README keeps what the tool is, how to install it and the first commands, and points to the guide on docs.ihasmail.org. Everything else moves, whole, into docs/ and CONTRIBUTING.md, where it is organized for readers who want the detail. Where the old README disagreed with the code, the code wins.
7.0 KiB
Known Stalwart problems
Things about Stalwart's 0.15 → 0.16 upgrade that bite, and what to do about each: the two server fixes you must make first, the administrator account, the settings Stalwart's converter drops without saying so, the certificate on the mail ports, and the extra recovery boot some store migrations need. For the short version, see the README.
Two things you must fix on the server first
Neither is something this tool can do for you, and both stop a migration dead.
preflight refuses on both, while the mail server is still running — but they
are worth knowing before you book a maintenance window, because fixing them is
a change to your directory, not a flag.
Remove or collapse multi-tenancy
v0.16 requires a tenant-scoped account to sit on a domain owned by that same tenant, for its primary domain and every alias. v0.15 imposed no such rule, so an install that is perfectly valid today can be unrepresentable in v0.16.
Run stalwart-migrate tenants to see who owns what.
- Where a domain has no tenant of its own and only one tenant's accounts use it, the conversion repairs it for you.
- Where two tenants genuinely share a domain, nothing can. Resolve it in v0.15 first: give each tenant its own domains, move the accounts into one tenant, or remove the tenants entirely.
Migrate as a directory account, not the built-in admin
A [authentication.fallback-admin] from config.toml authenticates perfectly
well right up to the moment the migration finishes, and then stops existing —
v0.16 keeps its configuration in the store, so the block defining it is never
read again. The migration itself still succeeds; what you lose is the ability
to verify it, recalculate quotas, or administer the server afterwards. The
next section has the detail.
You need a named admin account before you migrate
A config-file fallback admin will not survive the migration. If the only
administrator you have is an [authentication.fallback-admin] block in
config.toml — which is what stalwart --init sets up — you will come out of
the migration unable to administer the server.
Create a real account in the directory, with the admin role, and confirm you can log in as it before migrating. Four separate reasons, verified against a real 0.15.5 → 0.16.14 migration:
- v0.16 keeps its configuration in the store, not in a file. After the
migration the server is started with a config that is little more than a
pointer at the data store, so the old
config.toml— and the fallback-admin block inside it — is no longer read at all. That credential simply stops existing. migrate_v016.pygives every migrated account theUserrole, whatever it held before. An account that was an administrator in v0.15 comes out authenticating normally and refused every management operation.rehearsegenerates the operation that restores it — but the account has to exist in the directory for there to be anything to restore.- The account's local part must be unambiguous. v0.16 identifies an
account by local part plus domain, so if
[email protected]and[email protected]both exist, this tool refuses to restore either role rather than risk granting administrator rights to the wrong one. It says so rather than guessing; you then grant it by hand. - The role has to survive, not just the account.
tenant-adminhas no v0.16 equivalent and is not restored, so an account whose rights came only from it authenticates afterwards and is still refused management operations. Preflight cannot check this — it cannot know which roles the converter will carry across — so confirm on a clone, or immediately afterwards, that the account can still administer the server.
preflight refuses to proceed if the account you authenticate with is not in
the directory, so this is caught before anything is touched rather than after
the migration completes.
The practical check: make sure you can authenticate to the admin API as a
directory account — not as the fallback admin — that its local part is unique
across your domains, and that it holds admin rights through a role other than
tenant-admin.
Stalwart's own converter silently drops ACME
migrate_v016.py consumes every acme.* setting and emits nothing for them.
They are not reported as unmigrated either, so nothing warns you: the
certificate carries over, the provider that renews it does not, and TLS keeps
working until the certificate expires roughly ninety days later.
Check for acme.* in your dump before migrating, and recreate an
AcmeProvider afterwards if there was one. accountKey is server-set in
v0.16, so the existing ACME account cannot be carried over — the server
registers a new one on first issuance.
This tool does not yet generate that object for you. It should: the supplemental plan already does the equivalent for listeners. ARCHITECTURE.md §4.6a lists what else the converter drops.
A certificate that serves HTTPS may not serve the mail ports
A Certificate object carried into v0.16 with the right SAN is picked up by
the HTTP listener on its own. IMAPS, SMTPS and POP3S are not: they keep
serving a self-signed certificate until defaultCertificateId is set on
SystemSettings and the server is restarted.
This is the kind of thing that looks fine from a browser and surfaces as a mail client complaining days later, so check it as part of your post-migration verification: connect to 993 or 465 and confirm which certificate you are handed, not just to 443.
This tool does not set it for you. Like the AcmeProvider above, it should,
and the supplemental plan is where it belongs. Reported by
@kaya-eu.
The store migration may need one more recovery boot
This one is open, and it is the reason to rehearse on a clone. The recovery cycle boots the target version once, replays your settings into it, and stops. Across three real migrations, two different failures showed up that one extra recovery-mode boot cured:
- the settings apply failing on its very first object with
primaryKeyViolation, where re-running the identical apply against a fresh recovery boot went straight through; or - the next normal start panicking with "Upgrading to version 0.16 is a multi-step process", where booting recovery mode once more, letting it come up and stopping it cleanly was enough.
Never both on the same run — whichever appeared, one more recovery boot before the real start got past it. That panic is Stalwart's own, and it suggests the store migration is not finished when the single boot exits.
The likely fix is a settle boot after the apply. It is not in the tool, because getting an extra recovery boot wrong is its own hazard — see Do not boot recovery mode again afterwards. If you hit either failure, the extra boot is a manual step. Reported by @kaya-eu.