The problem with combining DNS CNAME records and anything else

January 10, 2025

A famous issue when setting up DNS records for domains is that you can't combine a CNAME record with any other type, such as a MX record or a SOA (which is required at the top level of a domain). One modern reason that you would want such a CNAME record is that you're hosting your domain's web site at some provider and the provider wants to be able to change what IP addresses it uses for this, so from the provider's perspective they want you to CNAME your 'web site' name to 'something.provider.com'.

The obvious reason for 'no CNAME and anything else' is 'because the RFCs say so', but this is unsatisfying. Recently I wondered why the RFCs couldn't have said that when a CNAME is combined with other records, you return the other records when asked for them but provide the CNAME otherwise (or maybe you return the CNAME only when asked for the IP address if there are other records). But when I thought about it more, I realized the answer, the short version of which is caching resolvers.

If you're the authoritative DNS server for a zone, you know for sure what DNS records are and aren't present. This means that if someone asks you for an MX record and the zone has a CNAME, a SOA, and an MX, you can give them the MX record, and if someone asks for the A record, you can give them the CNAME, and everything works fine. But a DNS server that is a caching resolver doesn't have this full knowledge of the zone; it only knows what's in its cache. If such a DNS server has a CNAME for a domain in its cache (perhaps because someone asked for the A record) and it's now asked for the MX records of that domain, what is it supposed to do? The correct answer could be either the CNAME record the DNS server has or the MX records it would have to query an authoritative server for. At a minimum combining CNAME plus other records this way would require caching resolvers to query the upstream DNS server and then remember that they got a CNAME answer for a specific query.

In theory this could have been written into DNS originally, at the cost of complicating caching DNS servers and causing them to make more queries to upstream DNS servers (which is to say, making their caching less effective). Once DNS existed with the CNAME behavior such that caching DNS resolvers could cache CNAME responses and serve them, the CNAME behavior was fixed.

(This is probably obvious to experienced DNS people, but since I had to work it out in my head I'm going to write it down.)

Sidebar: The pseudo-CNAME behavior offered by some DNS providers

Some DNS providers and DNS servers offer an 'ANAME' or 'ALIAS' record type. This isn't really a DNS record; instead it's a processing instruction to the provider's DNS software that it should look up the A and AAAA records of the target name and insert them into your zone in place of the ANAME/ALIAS record (and redo the lookup every so often in case the target name's IP addresses change). In theory any changes in the A or AAAA records should trigger a change in the zone serial number; in practice I don't know if providers actually do this.

(If your DNS provider doesn't have ANAME/ALIAS 'records' but does have an API, you can build this functionality yourself.)


Comments on this page:

By Arnaud Gomes at 2025-01-11 06:34:04:

Another complication would be flaky authoritative servers. Say the resolver has a CNAME cached, requests another record and the authoritative server fails to answer. Should the resolver fall back on the CNAME?

   -- A

The history as found in the RFCs is fairly messy.

The early DNS (RFC 881 / 882 / 883) did not have a rule restricting CNAMEs.

RFC 973 lists a bunch of fixes. WRT CNAME its complaint is about mismatches between the other records at the CNAME owner and target. Which makes sense if you view CNAME as being just about aliases for a canonical host name, but from a more modern perspective that seems like a limited and inflexible way to model names and services.

(At that point in time there was still mostly a view that systems connected to the network were doing timesharing and running a collection of disparate services that differed by protocol. The only example of virtual services was email, and it was treated as a special case. It wasn’t until the late 1990s that the idea of name-based services really became a concept in its own right, applicable to protocols in general, based on the lessons learned from scaling up http.)

Your observation about caches is also important, but there’s another twist. There was no negative cacheing in the DNS until RFC 2308 in 1998 (surprisingly late, I think!). CNAME + other data could have been fixed if early DNS had negative cacheing, by adding both QNAME+CNAME and a negative entry for QNAME+QTYPE to the cache when a resolver gets a CNAME response. Then subsequent queries which hit a negative cache entry could have checked the cache for a sibling CNAME that could be returned instead.

It’s a shame, CNAME is one of the most troublesome DNS warts.

Written on 10 January 2025.
« Realizing why Go reflection restricts what struct fields can be modified
IMAP clients can vary in their reactions to IMAP errors »

Page tools: View Source, View Normal.
Search:
Login: Password:

Last modified: Fri Jan 10 22:55:24 2025
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.