Issue Description
Version: 0.16.23 (Docker, ghcr.io/stalwartlabs/stalwart:v0.16.23), upgraded from 0.16.22 on 2026-09-21. Resolver: system. The container’s resolv.conf has a single nameserver (our provider’s validating resolver).
What happens
Outbound delivery to one recipient domain under .org that is DNSSEC-signed and whose MX hosts are Google Workspace (aspmx.l.google.com, alt1/alt2.aspmx.l.google.com) fails on every attempt:
INFO IP address lookup failed (delivery.ip-lookup-failed) ... hostname = "aspmx.l.google.com",
details = "Temporary Failure for aspmx.l.google.com: Connection failed: lookup error:
DNS resolution error: DNS error: DNSSEC validation failed", elapsed = 880ms
The message stays queued and bounces at expiry. It started 2026-09-17/18, the same days as the .org DNSKEY rollover described in Stalwart GitHub issue 3316 and hickory-dns issue 3963. In the same period the same Google MX hosts delivered normally (83 deliveries) for recipient domains that are NOT signed. Every DNSSEC failure since 09-17 is this one recipient domain.
Why the 0.16.23 fix does not seem to cover it
0.16.23 makes the DNSSEC resolver query one nameserver at a time, to avoid the parallel truncated-response race. Here only one nameserver is configured, so there is no second response to race with. After upgrading to 0.16.23 and force-retrying the queued message, it fails with exactly the same error.
What I verified (from the host and from inside the container’s network namespace)
dig +dnssec +bufsize=1232 DNSKEY orgvia the configured resolver →tcset (truncated), as expected.- Same query over TCP → NOERROR,
adset, 1319 bytes. TCP/53 to the resolver is reachable from inside the Stalwart container. - The recipient domain’s MX RRset validates (
adfrom the resolver;delvsays “fully validated”). DS google.comreturns a correct opt-out NSEC3 denial with RRSIGs (soaspmx.l.google.comshould be provably insecure).
Expected
The A/AAAA lookup of an MX host in an unsigned zone should resolve as Insecure and delivery should proceed (no DANE, since the MX zone is unsigned).
Notes
- Not every signed
.orgdomain is affected: another DNSSEC-signed.orgdomain delivered fine in the same window, so it may depend on how the.orgDNSKEY fetch (truncated over UDP) is cached or ordered. - Looks like the same hickory truncation / TCP-retry path as Stalwart GitHub issue 3316, but reachable with a single nameserver.
Reproduce
A DNSSEC-signed .org recipient domain with MX pointing to Google Workspace, sent from 0.16.23 with one upstream validating resolver.
I can share the recipient domain and a full trace privately if useful.
Expected Behavior
The A/AAAA lookup of an MX host that lives in an unsigned zone (aspmx.l.google.com, under google.com) should resolve as DNSSEC “Insecure”, and delivery to the DNSSEC-signed .org recipient domain should proceed normally, as it does for unsigned recipient domains using the same MX hosts. No DANE applies, since the MX zone is unsigned.
Actual Behavior
Every delivery attempt to that recipient fails before connecting: “delivery.ip-lookup-failed … hostname = aspmx.l.google.com … DNS error: DNSSEC validation failed” (also alt1/alt2.aspmx.l.google.com). The message stays in the queue, DSN delay warnings go to the sender, and it bounces at expiry. The same Google MX hosts deliver fine in the same period for recipient domains that are not DNSSEC-signed. Upgrading 0.16.22 → 0.16.23 and force-retrying did not change it. Started 2026-09-17/18 (.org DNSKEY rollover).
Reproduction Steps
- Run Stalwart 0.16.23 in Docker with the default (system) resolver, where the container’s resolv.conf lists ONE validating upstream resolver.
- Send a message to a recipient whose domain is under .org, is DNSSEC-signed (DS at .org), and has its MX on Google Workspace (
aspmx.l.google.com,alt1/alt2.aspmx.l.google.com). - Watch the delivery log: every attempt ends in delivery.ip-lookup-failed “DNSSEC validation failed” for the Google MX hosts, and the message stays queued.
- For comparison, send to an UNSIGNED domain that uses the same Google MX hosts: it delivers normally.
Relevant Log Output
2026-09-21T19:08:10Z INFO Delivery attempt started (delivery.attempt-start) queueId = 330564860025141760, queueName = "remote", from = "[email protected]", to = ["[email protected]"], size = 1975, total = 1
2026-09-21T19:08:10Z INFO TLS-RPT record not found (tls-rpt.record-not-found) ... domain = "signed-recipient.org", elapsed = 31ms
2026-09-21T19:08:10Z INFO MTA-STS policy not found (mta-sts.policy-not-found) ... domain = "signed-recipient.org", strict = false, elapsed = 106ms
2026-09-21T19:08:11Z INFO IP address lookup failed (delivery.ip-lookup-failed) ... domain = "signed-recipient.org", hostname = "aspmx.l.google.com", details = "Temporary Failure for aspmx.l.google.com: Connection failed: lookup error: DNS resolution error: DNS error: DNSSEC validation failed", elapsed = 880ms
2026-09-21T19:08:11Z INFO IP address lookup failed (delivery.ip-lookup-failed) ... domain = "signed-recipient.org", hostname = "alt1.aspmx.l.google.com", details = "Temporary Failure for alt1.aspmx.l.google.com: Connection failed: lookup error: DNS resolution error: DNS error: DNSSEC validation failed", elapsed = 139ms
Stalwart Version
v0.16.x
Installation Method
Docker
Database Backend
RocksDB
Blob Storage
RocksDB
Search Engine
Internal
Directory Backend
Internal
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