Bali, Indonesia
Insights

Why a CNAME on Your Root Domain Breaks MX and TXT Records

November 1, 2026
0:00
A common way this starts: someone points a root domain at a website platform or CDN by adding a CNAME, and the site loads fine. Then email stops arriving, SPF checks start failing, or a verification TXT record that was definitely added can't be found by the service checking it. The MX and TXT records still show in the DNS dashboard, so it looks like DNS is ignoring them. It isn't ignoring anything. A CNAME changes how every query for that name gets answered, not just web traffic.
A CNAME (canonical name) record does not mean 'send web visitors over there.' It means 'this name is an alias. For any question about it, go ask about that other name instead.' That covers every record type: A, AAAA, MX, TXT, CAA, all of them. Because of that, the DNS standards say a name holding a CNAME should hold no other data. RFC 1034 states the rule, and RFC 2181 restates it more firmly. The only exceptions are DNSSEC records like RRSIG and NSEC, which describe the CNAME itself. The logic is simple. If example.com is an alias for site.platform.example, an MX record sitting next to the alias is a contradiction. Do you use the local MX or the target's MX? The protocol avoids the question by not allowing both. The root of a zone, also called the apex, makes this worse. Every zone apex has to carry an SOA record (the zone's metadata) and NS records (which servers are authoritative). So a CNAME at the apex always conflicts with something, even before you add mail records. The problem isn't limited to the apex, though. A CNAME on any subdomain that also needs MX or TXT, such as a mail subdomain or a name used for domain verification, breaks the same way.
The failure makes sense once you follow a single query. Say a sending mail server wants to deliver to [email protected] and asks its recursive resolver for the MX records of example.com.
  1. The resolver works its way down to the authoritative nameserver for example.com and asks for type MX at that name.
  2. The authoritative server looks up the name and finds a CNAME. Under the standard lookup algorithm in RFC 1034, it doesn't go looking for MX at that name. It returns the CNAME, and if it is also authoritative for the target, it may include the target's answer too.
  3. The resolver sees the CNAME and restarts the same question with the new name: what are the MX records for site.platform.example?
  4. Whatever the target zone says becomes the answer for example.com. If the target has no MX records, the result is NOERROR with no MX data, usually called NODATA.
Notice what is missing: your own MX record never takes part. Depending on the authoritative software, the zone may have refused to load at all. BIND, for example, rejects a zone where a CNAME shares a name with other data. The dashboard may have accepted both records, or the provider may answer with only the CNAME. In each case, the outside world sees the alias. TXT lookups follow the same path. An SPF check for example.com gets the TXT records of the CDN hostname, which usually have no SPF policy for your domain at all. A verification service looking for its token gets someone else's TXT set, or nothing. From their side, your record doesn't exist. Caching adds a delay on top. Resolvers keep the CNAME for its TTL, and they can also cache the NODATA result for the target according to that zone's negative caching settings (RFC 2308). Fixing the record removes the cause right away, but some resolvers keep the old answer until their cache expires.
Mail failures here often look strange because SMTP has a fallback. When a domain has no MX records, RFC 5321 tells senders to treat the domain's address records as an implicit MX. The sender then resolves the A or AAAA records for example.com, follows the same CNAME, and gets the IP addresses of the web platform. So the sending server tries to open an SMTP connection on port 25 to a CDN or web host that was never meant to accept mail. The connection may be refused, may time out, or may reach something that rejects the recipient. Most MTAs treat connection problems as temporary, so messages sit in the sender's queue and retry for a while before bouncing. That is why it often gets reported as 'mail is slow or missing' rather than a clean error. On the support desk, this kind of report usually comes with a recent DNS change for the website, and the person who made that change rarely connects it to email.
Two views matter: what a normal resolver sees, and what the authoritative server is actually serving. Read-only dig queries cover both. Replace the domain and the nameserver with your own values.
BASH
# What a resolver returns for mail and TXT lookups
dig example.com MX +noall +answer
dig example.com TXT +noall +answer

# Is there a CNAME on the name itself?
dig example.com CNAME +short

# Find the authoritative servers, then ask one directly (no cache involved)
dig example.com NS +short
dig @ns1.example-dns.net example.com MX +norecurse +noall +answer
The telltale sign is an MX or TXT query whose answer starts with a CNAME:
TEXT
; Illustrative output format
example.com.             300  IN  CNAME  site.platform.example.
If you asked for MX and the answer section contains only a CNAME, or a CNAME followed by records belonging to the target hostname, the alias is overriding your records. If querying the authoritative server directly shows the CNAME but public resolvers still show something else, or the reverse, you are looking at caching. The real fix is the zone content, and the cache will catch up after the TTL. Don't rely on dig ANY for this check. Many servers now return a minimal or refused response to ANY queries, so a short answer there proves nothing. Asking for each record type separately is more reliable.
The fix is to stop putting a real CNAME on any name that needs other records. There are a few ways to do that, and which one fits depends on what the target platform needs and what your DNS provider supports. The plainest option is A and AAAA records at the apex, pointing at the IP addresses the platform gives you. These can sit next to MX, TXT, SOA, and NS without any conflict. The trade-off is maintenance. If the platform changes its IPs, you have to update your records, and a CDN that relies on hostname-based routing may not hand out stable IPs at all. The second option is a provider-side alias, sold under names like ALIAS, ANAME, or CNAME flattening. Your authoritative DNS provider resolves the target hostname itself and answers queries for your apex with plain A or AAAA records. Resolvers never see a CNAME, so your MX and TXT records are answered normally. This is not a standard record type that every server understands. ANAME went through the IETF draft process, but support and behavior come from your provider. Check in their documentation whether it handles IPv6, how it sets TTLs, and whether it works for names other than the apex. The third option is to move the CNAME off the apex. Point www at the platform with a CNAME, keep only address records or nothing web-related at the apex, and redirect the bare domain to www. This is often the cleanest setup when the platform requires a CNAME.
TEXT
; Conflicting: the alias shares a name with mail records
example.com.      IN  CNAME  site.platform.example.
example.com.      IN  MX 10  mail.example.com.

; Valid: apex keeps address and mail records, alias moves to www
example.com.      IN  A      192.0.2.10
example.com.      IN  MX 10  mail.example.com.
example.com.      IN  TXT    'v=spf1 mx -all'
www.example.com.  IN  CNAME  site.platform.example.
The same reasoning applies below the apex. If a subdomain needs its own MX or a verification TXT record, it can't also be a CNAME. Either give it address records or put the alias on a different name. When mail or verification breaks right after a website DNS change, query MX and TXT for the exact name and check whether the answer starts with a CNAME. If it does, the fix is structural, not a typo. Replace the alias with address records, a provider-side ALIAS or flattening feature, or a CNAME on www. Then confirm against the authoritative server, and give caches one TTL cycle before deciding whether it worked.