Issue Description
(Assistance from Claude)
With MTA-STS disabled (mtaSts.mode = disable), Stalwart v0.16.13/v0.16.14 still (a) builds an in-memory MTA-STS policy object with Mode::None, (b) advertises mta-sts. / _mta-sts. records for every domain in its DNS zone output, and (c) panics whenever a remote MTA fetches https://mta-sts.<domain>/.well-known/mta-sts.txt:
thread ‘tokio-rt-worker’ panicked at crates/common/src/config/smtp/resolver.rs:365:27:
internal error: entered unreachable code
In production this was a continuous panic storm (Gmail’s policy fetchers retry in bursts of ~4, all day, on both cluster nodes).
Expected Behavior
No crashes/errors.
Actual Behavior
Chain (v0.16.13 source)
Policy::try_parse (crates/common/src/config/smtp/resolver.rs:261): when mta_sts.mx_hosts is empty it falls back to SystemSettings.mail_exchangers / default_hostname — effectively never empty — and maps PolicyEnforcement::Disable → Mode::None, returning Some(policy) even though the feature is disabled. So session.mta_sts_policy is Some with mode: None.
The DNS record generator (crates/common/src/network/dns/records.rs:123, DnsRecordType::MtaSts) only checks is Some — it emits mta-sts. CNAME + _mta-sts. TXT “v=STSv1; id=…” for every domain, advertising MTA-STS that the operator disabled.
The HTTP handler (crates/http/src/request.rs:328, (“mta-sts.txt”, GET)) calls policy.to_string(); impl Display for Policy (resolver.rs ~line 360) has:
match self.mode {
Mode::Enforce => f.write_str(“enforce”)?,
Mode::Testing => f.write_str(“testing”)?,
Mode::None => unreachable!(),
}
→ panic on every fetch. Fetchers get a dropped connection and retry.
Expected
mode = disable should mean: mta_sts_policy = None, no mta-sts./_mta-sts. records emitted, and /.well-known/mta-sts.txt returning 404. Alternatively (RFC 8461 §5 offers mode: none as a real value for graceful shutdown), Display could legitimately serialize mode: none — but then the config needs to distinguish “publish mode:none” from “feature off”, and unreachable!() must go either way.
Reproduction Steps
mtaSts settings: {“mode”:“disable”,“mxHosts”:{}} (defaults otherwise), at least one domain + mail exchanger configured.
Observe the generated DNS records still include _mta-sts.<domain>.
curl -sk https://<server>/.well-known/mta-sts.txt → connection dropped; server log shows the panic above.
Stalwart Version
v0.16.x
Installation Method
Binary (Linux)
Database Backend
FoundationDB
Blob Storage
S3-compatible
Search Engine
Internal
Directory Backend
Internal
Additional Context
Workaround
Set mode = testing — Display becomes serializable and the panics stop; but disabled-yet-advertised remains the underlying bug. Also note the _mta-sts TXT id= in already-written DNS zones is not refreshed when the policy changes.
Environment: Stalwart v0.16.13 (also present in v0.16.14 source), FoundationDB build, 2-node cluster, Linux x86_64.
I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.
on
I have searched this support forum (open and closed topics) and confirm this is not a duplicate.
on
I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.
on