How Email Delivery Works Without MX Records: A Deep Dive into Fallback Mechanisms


1 views

When examining the DNS configuration for domainname.com, we notice something peculiar - there's no MX record present, yet emails to bob@domainname.com are successfully delivered. This seems to violate standard email protocols, but there's actually a logical explanation rooted in SMTP fallback behavior.

RFC 5321 (the SMTP protocol specification) includes an important fallback provision:

// Pseudo-code illustrating SMTP delivery logic
if (domainHasMXRecord(targetDomain)) {
    deliverToMXServers();
} else if (domainHasARecord(targetDomain)) {
    deliverToArecordIP(25); // Fall back to port 25
} else {
    return "550 No MX or A record found";
}

In our case, domainname.com has an A record pointing to 177.39.XXX.YY. When the sending server can't find an MX record:

  1. It checks for an A record
  2. Attempts delivery to that IP on port 25
  3. The mail server at that address accepts the message

The mail server appears to be configured with virtual domain aliasing. Here's what the Postfix configuration might look like:

# /etc/postfix/main.cf
virtual_alias_domains = domainname.com
virtual_alias_maps = hash:/etc/postfix/virtual

# /etc/postfix/virtual contents
@domainname.com   @domainname.com.br

The receiving mail server has two key components:

  • An SMTP listener on the IP from the A record
  • A virtual domain mapping that redirects @domainname.com to @domainname.com.br

Let's examine the relevant DNS records more closely:

# Both domains point to the same nameserver
$ dig NS domainname.com +short
ns1.domainname.com.br.

$ dig NS domainname.com.br +short 
ns1.domainname.com.br.

# And share the same IP address
$ dig A domainname.com +short
177.39.XXX.YY

$ dig A domainname.com.br +short
177.39.XXX.YY

While this setup works, it has some drawbacks:

  • Dependency on the A record makes migration harder
  • No priority handling (unlike MX records)
  • Some spam filters may penalize domains without MX records

When examining the DNS configuration for domainname.com.br and domainname.com, we observe an interesting phenomenon:

$ dig MX domainname.com.br
;; ANSWER SECTION:
domainname.com.br.  86179   IN  MX  10 domainname.com.br.

$ dig MX domainname.com
;; No MX records found

RFC 5321 (Simple Mail Transfer Protocol) specifies the fallback behavior when MX records are absent:

  1. First attempts to find MX records
  2. If no MX exists, falls back to A/AAAA records
  3. Connects to the IP directly on port 25

This is implemented in Postfix's source code (src/dns/dns_lookup.c):

if (mx == 0) {
    msg_info("%s: no MX hosts found, falling back to A/AAAA lookup",
        domain);
    if ((host = dns_lookup_host(domain, type)) == 0)
        return (0);
    result = dns_save_host(domain, host, pref);
}

Let's simulate the mail delivery process using Python:

import dns.resolver

def get_mail_servers(domain):
    try:
        mx_records = dns.resolver.resolve(domain, 'MX')
        return [str(mx.exchange) for mx in mx_records]
    except dns.resolver.NoAnswer:
        try:
            a_records = dns.resolver.resolve(domain, 'A')
            return [domain]  # Fallback to domain itself
        except dns.resolver.NXDOMAIN:
            return None

servers = get_mail_servers('domainname.com')
print(f"Mail servers: {servers}")  # Output: ['domainname.com']

The observed behavior suggests this mail server configuration (Postfix example):

# /etc/postfix/main.cf
virtual_alias_maps = hash:/etc/postfix/virtual
local_recipient_maps = $virtual_alias_maps

# /etc/postfix/virtual
bob@domainname.com   bob@domainname.com.br
@domainname.com      @domainname.com.br

While the fallback works, it's recommended to explicitly set MX records:

$ORIGIN domainname.com.
@       IN  MX  10 domainname.com.br.
@       IN  A    177.39.XXX.YY

This ensures predictable behavior across all mail servers and prevents potential delivery issues with stricter MTAs.