Skip to content
senn-techsenn-tech
Back to blog
Infrastruktur
Servers, Proxmox and network2026-10-27· By Franz Senn

Stalwart 1.0: no in-place upgrade, a mandatory migration

Stalwart 1.0 has been out since 26 October 2026, and anyone running 0.16.x cannot simply start the new binary. The vendor rebuilt the database schema. This post sorts out what the release contains, what to expect from the migration and which numbers are vendor claims only. A note on our own migration follows below.

Stalwart 1.0 in 70 words: Stalwart 1.0 is the first stable release of Stalwart Labs' open-source mail and collaboration server, which bundles SMTP, IMAP, JMAP, CalDAV and WebDAV in one Rust application. It uses a new database schema that 0.16 data cannot open. Existing installations therefore have to be copied into a new, empty store with the stalwart-migrate tool, starting from version 0.16.27. According to the vendor, ordinary updates are meant to be enough from here on.

No in-place upgrade from 0.16.x

The 1.0.0 release notes say it in the first paragraph: the release has several breaking changes and a new database layout, so existing 0.16.x deployments cannot be upgraded in place. The release post adds that a v1.0 server will not open a store created by an earlier version. The vendor justifies the cut by saying the schema is now stable and future releases will upgrade by update again. That is a promise by the vendor, and it only counts once later releases keep it.

The stalwart-migrate README describes the path. The new instance starts with empty storage, and the tool opens the old store read-only and copies into the new one while 0.16 keeps running. Each further run transfers only what changed, and run --final finishes with 0.16 stopped. The source has to be 0.16.27 (released 18 October 2026), older 0.16 versions have to be brought to it first. As of 5 November the README also states that the tool writes stores for Stalwart v1.0.3 and later.

The tool's schema document shows why the schema could not be converted in place. All numeric id spaces were re-sorted, not just extended. Of the names that exist in both 0.16.27 and 1.0.3, almost all server properties have a different id:

Shared names with a changed id, 0.16.27 vs 1.0.3 (percent)Server properties98 · 836 of 853Events95 · 558 of 585Permissions90 · 561 of 624User properties70 · 33 of 47Server objects59 · 68 of 1160100
Share of names present in both versions that carry a different numeric id. The counts are the vendor's table, the percentages are our rounding. The document concludes that any copy must go through names, never through raw ids. (source: SCHEMA_CHANGES.md, stalwart-migrate (retrieved 5 Nov 2026))

If your own scripts, exports or monitoring use raw numeric ids from the old instance, those places have to move to names. Anything that already works with names is unaffected by the move.

What the release brings

The release post cites close to 200 commits across more than 1,300 files, most of them for speed. Parsers for MIME boundaries, headers and Base64 now use SIMD and SWAR kernels, and the libraries mail-parser and encodify reach 1.0 together with the server. The performance figures are vendor claims: mail-parser is said to be three times faster than the Rust mailparse crate, Base64 decoding 22 times faster than the standard crate on an AMD EPYC server. Against Postfix 3.11 and Dovecot 2.4 on Azure servers with 8 vCPUs (EPYC Zen 5) and 32 GiB RAM, Stalwart is said to have been faster in 35 of 38 headline comparisons. We have not re-measured any of this.

For operations, these changes from the changelog matter most:

  • New search engine: It extracts text from PDF, Office documents (docx, xlsx, pptx), OpenDocument, EPUB and RTF, in attachments and in file storage. The search index is not copied: v1 rebuilds it after start, and results stay incomplete until then (stalwart-migrate README).
  • Migration as a copy: Account, document and thread ids and IMAP UIDs keep their values, so IMAP clients do not download their mailboxes again. OAuth tokens do not carry over, and CalDAV, CardDAV and WebDAV clients fetch their data once more because the entity tags change.
  • SSRF protection for outbound HTTP requests: The changelog names webhooks, OIDC discovery, AI providers and DNS providers. An OIDC directory that has to reach an identity provider on a private network needs the superuser setting trustedProvider from 1.0.2 on.
  • Stricter OAuth: The OAuth profile for public clients is now fully enforced, and with an external OIDC provider you have to check its capabilities, according to the changelog. Since 1.0.3, third-party apps also need the new Stalwart scopes.
  • Post-quantum DKIM2: 1.0.0 added a composite signature of ML-DSA-44 and Ed25519. 1.0.2 replaces it with pure ML-DSA-44, following draft-ietf-dkim-dkim2-spec-08. That is a draft, not an adopted standard.

The 1.0.0 changelog also lists "multiple bug and security fixes" without naming individual vulnerabilities. That is no sign of an emergency update, but the migration is mandatory as soon as you want 1.0.

Flow of a Stalwart migration0.16.27 sourcestays in service, openedread-onlypreparereview settings, recorddecisionsrun, repeatedcopies only changes per runrun --finalwith 0.16 stoppedverify / reportcompare, list droppedobjects
Command order as given in the tool README. Our own drawing. (source: README, stalwart-migrate (retrieved 5 Nov 2026))

The private tests

On 16 October 2026, Stalwart announced in "Private Tests, Public Code" that the test suite and its fixtures move to a private repository. New features will be developed privately and published as a finished commit under the AGPL. The vendor's reasoning: a test suite is an oracle for AI agents, which can use it to produce clones under a different license. The vendor states that the AGPL does not count tests as source code, and says it will review the decision every year and bring the tests back once there is legal protection against such clones.

For operations this means the public code can still be read and built, while whether it is tested can no longer be checked from outside. We found no independent discussion of it. The Hacker News submission of the post had 4 points and no comments when we checked on 5 November. Each operator has to decide for their own system whether that is enough.

Measurement basis of this post

QuantityValueUnitDateMeasured by
Stalwart version in our use0.16.25version27 Oct 2026our measurement, homelab mail server VM (Docker image pinned)
Latest version per changelog1.0.0, later 1.0.3version27 Oct and 5 Nov 2026our reading of the changelog
Shared names with a changed id (server properties)836 of 853names5 Nov 2026vendor figure, SCHEMA_CHANGES.md
Commits and files in the releaseabout 200 / over 1,300count26 Oct 2026vendor figure
Stalwart vs Postfix and Dovecotfaster in 35 of 38 comparisonscomparisons26 Oct 2026vendor figure, Azure 8 vCPU EPYC Zen 5, 32 GiB, not re-measured

The first two rows are our own measurements, the rest are vendor figures. We keep them apart on purpose.

What changes with the license

According to the sources, nothing new changes in licensing. The README names a dual license of AGPL-3.0 and the Stalwart Enterprise License v2 (SELv2), with the texts in the LICENSES folder (AGPL-3.0-only.txt, Apache-2.0.txt, LicenseRef-SEL.txt). There is no LICENSE file in the repository root. By the README, about 85 percent of the features are in the AGPL edition and the rest is the Enterprise edition. The schema document lists the permission interactAi among the enterprise-only items. Anyone who modifies the code and offers it over a network stays within the AGPL obligations.

Migration in the right order

  1. Bring the source to 0.16.27. The tool requires that version.
  2. Back up the data and find every place that uses raw ids instead of names.
  3. Run prepare to review how settings convert and record the open decisions.
  4. Run run against a test copy and read report, which lists dropped, changed and truncated objects.
  5. Plan a way back. The old instance is never written to and can keep running until the switch, and the tool also has rollback.
  6. After the switch, test sign-in, especially OAuth clients and webmail, then DAV clients and search until the index is rebuilt.

A move that migrates the mailboxes and silently breaks sign-in is not a successful move. So the test with a real account belongs before the old instance is retired.

Update of 5 November 2026

This post originally contained a bar chart whose percentages used denominators that did not match the vendor's table, a link to a Hacker News thread that pointed to a different discussion, and statements about type changes that the source does not make. We corrected those passages against the sources, which is why the post carries a new update date. We migrated our own server to 1.0.2 on 2 November, and the numbers and pitfalls are in Migrating to Stalwart 1.0 on a homelab: the steps, the numbers and seven traps. A comparison with other mail systems is in Stalwart, Axigen and Exchange in operation. The topic hub Servers, Proxmox and network collects more on running servers. If you would rather not plan a mail server move alone, our offers are on the services page.

Further reading

Questions?
Can I upgrade Stalwart 0.16 to 1.0 in place?+

No. The 1.0.0 release notes say existing 0.16.x deployments cannot be upgraded in place because the database layout is new. The stalwart-migrate tool copies accounts, mail and settings into a new, empty v1 store. The starting point has to be 0.16.27.

Does the old server keep running during the migration?+

Yes. The tool opens the old store read-only, and every run copies only the changes since the previous one. Only run --final needs 0.16 stopped. OAuth tokens are not carried over, so users sign in again in OAuth clients.

Is Stalwart 1.0 still free software?+

The community edition is licensed under AGPL-3.0, and according to the README about 85 percent of the features are in it. The rest is the Enterprise edition under the proprietary SELv2. The repository is dual-licensed. There is no LICENSE file in the repository root, the texts sit in the LICENSES folder.