Issue Description
Note: domain names are written with " DOT " because of the new-user link limit.
Outbound delivery to mail DOT de fails at the MX lookup stage with “DNSSEC validation failed”, although the zone validates cleanly with dig and delv on the same host. The failure occurs with dane set to disable, so the DANE strategy has no effect on it. Messages stay queued until they expire.
The resolver in use is a custom one (UDP and TCP entries pointing at two public validating resolvers), not the Docker internal resolver. Other signed zones using algorithm 8 and algorithm 13 validate correctly against the same resolver. The failing zone signs with algorithm 10 (RSA/SHA-512) and currently publishes 5 DNSKEY records.
Expected Behavior
The MX lookup succeeds and delivery proceeds, the same way it does for posteo DOT de (algorithm 8) and mailbox DOT org (algorithm 13).
Actual Behavior
The MX lookup fails immediately on every attempt, the message is rescheduled, and the queue entry eventually expires. The elapsed time of 2 ms suggests the failure happens without a network round trip.
Reproduction Steps
- Configure a custom DNS resolver with udp and tcp entries, not the system or Docker resolver.
- Set dane to disable on the outbound TLS strategy.
- Restart the server so the setting is picked up.
- Send a message to any recipient at mail DOT de.
Relevant Log Output
INFO MX record lookup failed (delivery.mx-lookup-failed) queueId = 328571896014597120, queueName = “remote”, domain = “mail DOT de”, causedBy = DNS error (mail-auth.dns-error) { details = “DNS error: DNSSEC validation failed” }, elapsed = 2ms
INFO Message rescheduled for delivery (queue.rescheduled) queueId = 328571896014597120, queueName = “remote”, nextRetry = 2026-09-09T13:00:38Z, expires = 2026-09-12T12:01:29Z
External validation from the same host succeeds:
delv TLSA _25 DOT _tcp DOT mx02 DOT mail DOT de
; fully validated
TLSA 3 1 1 9730904A64883FB665C97071DC77C86515F0DEF54DA120EE33B3796939CD171E
TLSA 3 1 1 AAFECCBE29EDB69BBB13D78011697844BFACA8D30108A892377B0A14059DBD01
RRSIG TLSA 10 5 600 20260920004933 20260906004933 31896
The DNSKEY response is 1326 bytes and arrives over UDP without the tc flag, so truncation is not involved:
dig +dnssec +notcp DNSKEY mail DOT de
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1
;; MSG SIZE rcvd: 1326
Stalwart Version
v0.16.x
Installation Method
Docker
Database Backend
SQLite
Blob Storage
RocksDB
Search Engine
Internal
Directory Backend
Internal
Additional Context
Stalwart version: 0.16.21
Installation method: Docker
DNS resolver: custom, udp and tcp entries for two public validating resolvers
Comparison across German providers, all queried against the same resolver:
posteo DOT de mx01 DOT posteo DOT de algorithm 8 DANE verification passed
gmx DOT net mx00 DOT emig DOT gmx DOT net algorithm 8 not tested
web DOT de mx-ha02 DOT web DOT de algorithm 8 not tested
freenet DOT de mx DOT freenet DOT de algorithm 13 not tested
mailbox DOT org mx1 DOT mailbox DOT org algorithm 13 not tested
mail DOT de mx01 DOT mail DOT de algorithm 10 MX lookup fails
The troubleshooting tool reports the MX lookup as successful for this domain and only shows the error at the TLSA step. That does not match what the delivery path does and made the problem harder to locate.
Possibly related: with dane set to optional, the IP address lookup for hosts under olc DOT protection DOT outlook DOT com also failed with “DNSSEC validation failed”, which blocked delivery to all Exchange Online recipients. That stopped after setting dane to disable and restarting. The TLSA SERVFAIL handling fixed in 0.16.20 works as intended here, the log shows “TLSA record not DNSSEC signed” followed by successful delivery for those hosts.
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