MX record DNS bug lacking final dot

Issue Description

When using Stalwart as DNS for MX records, the name of MX records does not end with a dot, unlike the name and therefore MX fails.

Expected Behavior

A good MX record, adding final dot to the record if not existing. I strongly believe all DNS providers would act the same as RFC 1034. The code allows has specific dots for the name of the record (but not the value).

Actual Behavior

Does not add any dot and therefore putting example.com as MX host would result on DNS to MX example.com.example.com.

Reproduction Steps

  1. Ask Stalwart to change DNS with MX records.

Stalwart Version

v0.16.x

Installation Method

Binary (Linux)

Database Backend

MySQL

Blob Storage

MySQL

Search Engine

MySQL

Directory Backend

SQL

Additional Context

Using OVHCloud as DNS provider.

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

Let me look into this DNS MX record handling in the Stalwart source code.

The bug is confirmed in the source code. Looking at the DnsRecordType::Mx branch in crates/common/src/network/dns/records.rs:

DnsRecordType::Mx => {
    for mx in &network.info.mxs {
        records.push(NamedDnsRecord {
            name: format!("{domain_name}."),   // ✅ trailing dot on the record name
            record: DnsRecord::MX(MXRecord {
                exchange: mx
                    .hostname
                    .as_deref()
                    .unwrap_or(default_host)
                    .to_string(),              // ❌ no trailing dot on the exchange value
                priority: mx.priority as u16,
            }),
        });
    }
}

The name field correctly gets a trailing dot (format!("{domain_name}.")), but the MX exchange value (the hostname the MX record points to) does not get one. Per RFC 1034, a fully-qualified domain name used as an MX exchange must be absolute (i.e., end with a dot) when submitted to DNS providers; without it, providers like OVHCloud will append the zone origin, turning mail.example.com into mail.example.com.example.com.

The same pattern is correctly handled elsewhere in the same file (e.g., CNAME targets use format!("{default_host}."), SRV targets use format!("{}.", ...)) – so the fix is consistent with what is already done: the exchange field should be format!("{}.", mx.hostname.as_deref().unwrap_or(default_host)).

This looks like a genuine bug worth flagging to the maintainers. A human staff member will follow up on next steps.

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong. If you found it useful, mention @helpbot in any reply to ask follow-up questions and the bot will respond again.

This has been fixed already in dns-update 0.2.7 which will be released during this week.

I’m with OVH and can confirm this bug on 0.16. Will manually edit for now.