Why You Can't CNAME the Apex
You buy example.com, you deploy something, and the host tells you:
Point your domain at
d3jp940diwkqq6.cloudfront.net
So you open your DNS provider, go to add a CNAME for example.com, and either the form
refuses you or — worse — it accepts and something subtly breaks. Meanwhile www.example.com
takes the exact same CNAME without complaint.
This trips up nearly everyone once, and the usual explanation ("you just can't, use an ALIAS
record") is true and explains nothing. The actual reason is a single sentence written in
1987, and it's worth understanding, because it's also a large part of why www stuck around
for thirty years.
First, what the apex is
DNS is a tree of labels, and a zone is a contiguous chunk of that tree under one
administrative authority. When you register example.com, the .com operators create a
delegation — NS records in the .com zone saying "for anything at or under
example.com, go ask these nameservers instead."
The apex of your zone is the zone's own name: example.com itself. You'll also see it
called the zone apex, the root of the zone, the naked domain, or the bare domain.
They all mean the same thing: the topmost name in the zone, with nothing to the left of it.
www.example.com is not the apex. It's an ordinary node inside the zone, one label deeper,
and it is in no way special — it's a hostname with good PR.
That difference is the whole story here.
Two record types are mandatory at an apex, and their presence is what makes it a zone at all:
- SOA (Start of Authority) — exactly one. It declares this name as the top of a zone and carries the zone's operational parameters: the primary nameserver, the admin contact, the serial number, refresh/retry/expire timers, and the negative-caching TTL.
- NS — the authoritative nameservers for the zone. These have to match the delegation the parent published, or resolution gets inconsistent.
This is from RFC 1034, and it's not optional or conventional. A name with no SOA is not a zone apex. A zone apex with no SOA is broken.
So: the apex always has other records at it. Hold onto that.
The rule
RFC 1034 §3.6.2, from November 1987:
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.
RFC 2181 §10.1 later tightened "should" into the operational requirement everyone actually
implements, with one carve-out for DNSSEC records (RRSIG, NSEC) which must be allowed to
sit alongside a CNAME for the signature chain to work.
That's it. That's the whole restriction:
A name with a CNAME may have no other records.
Combine it with the previous section and the conclusion is forced. The apex must have SOA and NS. A CNAME forbids all other records. Therefore the apex can never hold a CNAME. It isn't a policy decision by your DNS provider or a limitation of their UI — it's arithmetic on two rules.
Why the rule exists
It's tempting to read the restriction as arbitrary. It isn't, and the reason gets at what a CNAME actually means.
A CNAME does not say "also look over there." It says this name IS that name — the target is the canonical name and this one is merely an alias for it. The correct behaviour on encountering a CNAME is to abandon the name you asked about entirely and restart the query against the target, for whatever record type you originally wanted.
That's a total substitution, which is why coexistence is incoherent. Suppose you could write:
example.com. CNAME target.example.net.
example.com. MX 10 mail.example.com.
Now a mail server looks up MX for example.com. Two contradictory answers are available:
follow the CNAME and use whatever MX target.example.net has, or use the local MX record
sitting right there. Nothing in the protocol says which wins. Two resolvers could reasonably
disagree, and — because answers get cached independently by record type — the same resolver
could disagree with itself depending on which record it happened to cache first.
The phrase in the RFC is precise about the goal: "the data for a canonical name and its aliases cannot be different." An alias that only partially aliases isn't an alias. So the spec forbids the ambiguity rather than trying to arbitrate it.
Once you see it that way, the apex restriction stops being a special case. There's no rule about apexes at all. There's one rule about CNAMEs, and the apex just happens to be a name that can never satisfy it.
The same logic bites elsewhere, for the same reason: you can't put a CNAME at a delegation point either, because that name already carries NS records for the child zone.
Why this suddenly started mattering
The rule is from 1987 and caused nobody much grief for a long time, because you pointed domains at IP addresses. You had a server, the server had an address, you wrote an A record. No aliasing needed.
Modern hosting broke that assumption. CloudFront, ALBs, Netlify, Vercel, Heroku, Fastly,
GitHub Pages — none of them will give you a stable IP, because they don't have one to give.
The address behind d3jp940diwkqq6.cloudfront.net varies by region, by point of presence,
by load, and changes without notice. The hostname is the contract; the addresses behind it
are an implementation detail they reserve the right to change at 3am.
"Follow this hostname wherever it goes" is precisely what CNAME is for. So the entire industry standardised on an instruction that works everywhere in your zone except at the one name you actually want to use.
And here's the bit worth noticing. For years, this made the layout obvious:
www.example.com→ one-line CNAME to your CDN. Trivial.example.com→ not expressible. A research project.
Which is a genuine, unglamorous, technical reason www outlived its usefulness as a
convention. It wasn't nostalgia. www was the one that worked. The apex was the awkward
case, so plenty of sites made www canonical and redirected the bare domain to it — the
opposite of what most people do today.
The workarounds
Provider-side pseudo-records (ALIAS / ANAME / CNAME flattening)
The one nearly everybody uses. Route 53 calls it an alias record, Cloudflare calls it CNAME flattening, DNSimple and others call it ALIAS or ANAME.
The crucial thing to understand: none of these are a DNS record type. There is no ALIAS record on the wire, and no RFC defines one. You will never see one in a packet capture.
What actually happens is that your authoritative nameserver does the work. You tell Route
53 "this apex is an alias for d3jp940diwkqq6.cloudfront.net." When a query arrives for
example.com, Route 53 resolves that target itself, server-side, and returns the resulting
addresses as ordinary A/AAAA records for example.com. The client sees a completely
normal answer and never learns aliasing was involved. The protocol is untouched; the
indirection is hidden inside one implementation.
That design has consequences worth knowing:
- It's a provider feature, not a DNS feature. It only exists if whoever hosts your zone implements it. Move your DNS to a provider that doesn't, and your apex stops working.
- It can't be replicated by a zone transfer. What AXFRs out is the flattened A records at whatever they were when the transfer happened, not the aliasing intent.
- The resolution happens from the nameserver's vantage point, not the client's. If the target uses geographic DNS load-balancing, the target sees your DNS provider's location rather than the end user's, which can route people to the wrong region. In practice this is a non-issue for Route 53 → CloudFront, since alias targets there are handled internally and CloudFront does its own edge routing on the anycast address anyway. It's a real consideration when flattening a CNAME to a third-party host.
- Targets are often restricted. Route 53 alias records can only point at AWS resources (CloudFront, ALB, S3 website endpoints, API Gateway…) or another record in the same hosted zone. You can't alias to an arbitrary external hostname.
- They're usually free to query. Route 53 doesn't bill for alias queries to AWS targets, where a normal record costs per million. Minor, but real at volume.
You also need this at the apex specifically. Once you're one label deep — www — a plain
CNAME works fine and none of the above applies.
Just hardcode the A records
Look up the addresses, write them in, move on. It works right up until it doesn't. Providers rotate addresses deliberately and without telling you, so this is a time bomb with a fuse of unknown length. Defensible for a server whose IP you control. Not defensible in front of a CDN.
Make www canonical and redirect the apex
Some registrars offer an HTTP redirect service at the apex — a tiny web server whose only
job is to 301 example.com to www.example.com. The apex gets A records pointing at the
registrar's redirector, www gets the CNAME, and the awkward name is handled at the HTTP
layer instead of the DNS layer.
This is why some large sites still serve www as canonical. It's not a stylistic preference
left over from 1998; it was the shape that worked.
HTTPS/SVCB records — the actual protocol fix
RFC 9460 (2023) introduced the SVCB and HTTPS record types, and they finally address
this at the protocol level rather than around it.
An HTTPS record in AliasMode — priority field set to 0 — does at the apex what CNAME
cannot:
example.com. HTTPS 0 target.example.net.
This is legal at the apex because it's a normal record type with no exclusivity rule. It coexists with SOA and NS perfectly happily. RFC 9460 calls out apex aliasing as an explicit design goal, not an accident.
The catch is client support. HTTPS records are genuinely deployed — Chrome, Firefox and
Safari query them, mainly for HTTP/3 advertisement and Encrypted Client Hello — but they're
HTTPS-specific by construction, and anything that isn't a modern browser will ignore them
entirely. You still need A/AAAA records at the apex for everyone else, which means you still
need the provider-side alias, which means the HTTPS record isn't yet replacing anything.
It's the correct long-term answer and not yet a usable one on its own. Worth knowing exists; not worth restructuring your zone around today.
What about DNAME?
DNAME (RFC 6672) is the record people reach for next, and it doesn't help here.
DNAME redirects an entire subtree: a DNAME at example.com rewrites
anything.example.com to anything.example.net. What it explicitly does not do is
affect the owner name itself. example.com is not covered by its own DNAME.
So a DNAME at the apex would redirect every subdomain you have while leaving the apex — the one name you were trying to fix — exactly as broken as before. It solves the opposite problem to the one you have.
The short version
- A zone apex must carry SOA and NS records. That's what makes it a zone.
- A CNAME forbids any other record at the same name, because a CNAME means total substitution and partial aliasing would be ambiguous.
- Those two rules can't both hold at the apex, so a CNAME there is impossible. There is no separate "apex rule."
- ALIAS/ANAME/flattening are one authoritative nameserver quietly resolving the target for you and returning plain A records. Convenient, invisible to clients, and entirely proprietary.
wwwnever had this problem, which is a real reason the convention survived long past the point anyone could explain why it existed.
Seen in the wild: the csv-helper.com fix, where
the apex is a Route 53 alias to CloudFront and www is an ordinary record pointed at the
same place.
Comments
No comments yet. Be the first!