Category Archives: DNS

Health checks and Multi-value DNS records in AWS Route53

A lesser understood feature of AWS Route53 is the ability to create multi-value records and control which values are published using health checks.

For reference, a multi-value record is something like:

$ dig -s

Let’s say that whatever it is that responds on has experienced a service interruption. What’s the best way to ensure traffic doesn’t flow to that address?

The typical way to create this type of record is to create a single record in AWS Route53 and add 3 IP addresses to the value, like so:

Screenshot 2022-01-05 at 18.02.51

However, to remove an IP from that record, you would need to edit the record itself, and then re-edit when the service recovers.

Instead, you can create 3 multi-value records like so, associating each with a health check that refers to the IP address in the record:

Screenshot 2022-01-05 at 18.09.59

Each of these records is associated with one of the following health checks:

Screenshot 2022-01-05 at 18.15.00

At this point, you can decide whether you want your health checks to be dynamic, or if you want to disable them and use the inversion feature of health checks to use them as on/off switches for the IP addresses.

If they’re dynamically used, and the health check goes into an unhealthy state, the IP address associated with that record will be dropped from the response. Alternatively, you can invert a disabled health check to achieve the same effect, which may be a more appropriate method to integrate this mechanism into existing tooling.

$ dig -s

Crucially, if all health checks are unhealthy (or inverted) AWS Route53 will stop making assumptions are publish all the IP addresses associated with the record.

$ dig -s


Basic guide to the issues around CNAME at the zone apex

What is a CNAME?

In DNS, CNAME stands for “canonical name”.

“Canonical” is one of those words you hear every now and then in technology discussions, but not many people are exactly sure what it means. In effect, it means “official”, which can be further extrapolated to “universally accepted”.

So in a DNS zone file, a CNAME looks like this: 3600 IN CNAME

In this case, the canonical name for the server which hosts is:

An alias (“also know as”) of that canonical name is:

So if you request this name, which is an alias, the response you will get will be data for the canonical record, for any type of record. For example, if you request the MX data for, you will/should receive the MX data for

At this point, it is important to understand that is an alias of, and not the other way around.

What is the zone apex?

The zone apex is that part of the a DNS zone for which data exists for the entire domain, rather that a specific host in the domain.

So if you want to define an MX records for the entire domain,, you would create that record at the apex: 3600 IN MX

Its worth noting that there is a difference between the default record type for a domain and the zone apex:

* 3600 IN A

The default value for a particular record type defines the data that should be returned if a request is received for a record type which does not have a specific match is the zone file.

What’s a CNAME at the zone apex?

A CNAME at the zone apex looks like this: 3600 IN CNAME

This is a common requirement for website owners who want to advertise their website without the “www” prefix and who also use the services of a 3rd party web hosting company who cannot provide them with a dedicated ip address and instead provide them with a canonical name for the website running on their infrastructure.

Why is it not allowed?

Given that so many web owners have the requirement outlined above, it seems incredulous that this isn’t allowed, which is why this is such a hot topic.

Firstly, let’s clarify that there is no explicit RFC rule that says “you can’t have a CNAME at the zone apex”.

What the RFCs do say is that if you define a CNAME with a name (the left side of the record declaration) of “”, you can’t create any other record of any other type using the same name. For example, the following would be non-compliant: 3600 IN CNAME  3600 IN MX

The reason for this goes back to understanding that the “alias” is the left side and the “official” name is the ride side. If something is “official”, there can only be one version of it. The first record in the above sequence tells DNS that is “official” for, so DNS doesn’t want to know about any other records for

But, you’ll ask, why can’t DNS simply segregate “officialness” based on the record type? The answer most top software testing companies will give you to this is that the DNS standard came into being long before HTTP or any contemplation of shared web hosting, and it is no longer practical to reverse engineer all of the DNS software that has grown out of the standard to fit this specific use case.

Is this strict?

This is where is starts to get interesting.

Given that so many people want CNAMEs at their zone apex ($$$$), many software developers and their product managers have taken a sideways look at the RFC and determined that it permits a degree of flexibility in its implementation:

If a CNAME RR is present at a node, no other data should be present; this ensures that the data for a canonical name and its aliases cannot be different.

The key phrase is “should be”. The argument runs that the absence of the phrase “must be” is in fact a license to interpret the standard more liberally, and there are DNS server implementations on the market that will allow CNAME records to co-exist with other records with the same name.

If you’re using a web hosting or DNS provider who says you can have a CNAME at the zone apex, they will be using such an implementation. This isn’t something that exists only in the dark, backstreets of web hosting. Global internet services providers like Cloudflare have permitted CNAMEs at the zone apex.

In truth, this interpretation exists on very shaky foundations. There is a more detailed discussion of this issue here.

How does this problem manifest itself?

RFCs exist to allow different people design software that will interoperate. If person A is writing code to implement a DNS server, and person B is writing software to implement a DNS client. If they both follow the standard, the 2 pieces of software should work together. The RFC doesn’t tell them how to write code, but it does tell them how their code should behave.

When people beginning interpreting the intent of an RFC, nothing good comes of it. It may not be immediately apparent, but the longer software exists, the more edge cases it has to deal with, and that’s where it becomes important that one piece of software can anticipate the response of another.

In terms of a practical example, this is really good:

In this case, MS Exchange Server 2010 stopped delivering mail to addresses whose DNS zone had a CNAME at the zone apex. The Exchange mail server was relying on a local DNS cache. Previously, someone had queried an A record for, and received a CNAME response. That data was cached. Later, when the MX record for was queried, the cache ignored the fact that the cached record was an A record (this was compliant behaviour) and returned a CNAME. The Exchange server correctly rejected this as CNAMEs are not valid data for MX queries.

Are there workarounds?

The first workaround is to not implement the RFC standard. Some providers will tell that this is their workaround, but it isn’t. It’s just chicanery, and you should avoid it.

The big cloud hosting companies are the best place to go for workarounds. Amazon AWS have a black box solution in Route53 which allows CNAMEs at the zone apex if the canonical name is an AWS resource identifier (like an ARN for an Elastic Load Balancer).

The most en vogue workaround at the moment is what is called CNAME flattening.

What is CNAME flattening?

DNS server software that implements CNAME flattening permits the user to create multiple CNAMEs of the same name with different official values, which allows the user to create a CNAME at the zone apex. When you configure the zone file in this way, the server will accept it and start as normal.

When a query is then received for one of these records, rather than return the CNAME value, the server will go off and query the CNAME value, and any subsequent values, until it gets to an IP address, and then return that IP address as the response to the original query.

Is CNAME flattening standards compliant?

Yes and no.

On the one hand it permits the existence of something that the RFC says is not permitted, but equally, it behaves in a way that is RFC compliant.

Whether a user wants to rely on CNAME flattening is something they will have to make a call on them according to their individual circumstances.