I want to start by saying how much I respect the work you’ve put into Stalwart — it’s genuinely impressive, and I’ve been following the project with a lot of enthusiasm.
But I have to be honest: I’ve been trying to migrate from v0.15.5 to v0.16.10 for a week now, and the configuration experience has become so painful that I’m seriously starting to consider moving to a different mail server — not because of the migration itself, but purely because of the new configuration system.
Here’s what I’m running into:
The declarative bulk operations approach makes it nearly impossible to achieve a clean, idempotent configuration — even for basic things. For example, to set a basic SystemSettings object, you must provide a defaultDomainId. But to have a defaultDomainId, you first need to create a Domain object. This is a classic chicken-and-egg problem: the Domain object makes the configuration non-idempotent (subsequent applies fail with “object already exists” errors), and at the same time — as you yourself noted — it is not advised to treat domains, accounts, aliases, and DKIM keys as idempotent settings, since they are management objects rather than configuration
On top of that, the strict operation ordering — destroy first, then update, then create — makes it extremely difficult to write a configuration that applies cleanly. You constantly run into errors like “cannot update this because the object doesn’t exist yet”, and in most cases that object is a reflink (#) that fundamentally cannot be created first, since destroy runs before create.
Snapshots, in theory, could help — but recreating all objects on every apply doesn’t feel safe to me in a production environment.
I genuinely feel stuck. A week in, and I still can’t get the server into a clean, reproducible state. It’s exhausting.
I think having even a minimal static config file for foundational objects — network listeners, basic system settings, and similar primitives — would make a world of difference. It doesn’t have to cover everything, just the pieces that need to exist before anything else can reference them.
I really hope this feedback is useful. I want to keep using Stalwart — I just need the configuration story to be workable.