DNS CNAME Flattening: Pointing Root Domains to CDN Without Breaking DNS Rules

A few years ago a customer came to us with a deceptively simple request: they wanted example.com - no www, just the bare root - to sit behind our CDN. Their developer had added a CNAME at the apex, it worked in their test resolver, then mail delivery collapsed and their zone wouldn't even load on their secondary provider. I've seen this exact ticket at least fifty times in the last decade, and it always comes down to the same DNS rule most folks don't hit until they try to put a CDN in front of their root domain.

Why a CNAME at the Apex Breaks DNS

By definition the DNS apex - that’s example.com itself without any subdomain label - has to hold SOA and NS records. That’s not optional; it’s how RFC 1034 defines authority for the zone. A CNAME, on the other hand, is exclusive by design. If a name has a CNAME, it can’t have any other record type alongside it. You can’t have both, so when you try to create example.com. CNAME cdn-provider.net. you’re asking the apex to be both an authoritative zone cut and an alias at the same time.

Most authoritative software will just reject the zone outright. BIND will throw a CNAME and other data error on load, PowerDNS will refuse to serve it, and if you somehow force it through, resolvers get confused about where to find your MX, TXT, or DNSSEC records. I once spent a long night debugging why a client's SPF and DKIM validation had silently failed after a “quick CDN migration” - they’d flattened nothing, just forced a CNAME at the root on a permissive provider, and all their TXT records vanished from responses. If you're offloading parts of your domain to edge infrastructure, DNS NS Delegation for CDN: Offloading Domain Resolution to Edge Networks is a safer pattern for subdomains, but it doesn't solve the apex problem.

Here’s what an illegal zone looks like and what your nameserver will tell you:

; This zone file will FAIL to load - do not use
$ORIGIN example.com.
@   IN  SOA   ns1.example.com. admin.example.com. 2024010101 7200 3600 1209600 3600
@   IN  NS    ns1.example.com.
@   IN  NS    ns2.example.com.
@   IN  MX    10 mail.example.com.
@   IN  CNAME cdn.example.net.  ; ILLEGAL: CNAME cannot coexist with SOA/NS/MX
www IN  CNAME cdn.example.net.  ; This is perfectly legal

; BIND check result:
; $ named-checkzone example.com db.example.com
; dns_master_load: db.example.com:7: example.com: CNAME and other data

How CNAME Flattening Resolves the Conflict

Flattening doesn’t bend the DNS spec - it works around it. Instead of publishing a CNAME at the apex, your authoritative DNS server does the resolution work for the client ahead of time. When a resolver asks for example.com IN A, the authoritative server sees an ALIAS or ANAME record pointing at cdn.example.net, performs its own lookup for that target, and then returns the final A or AAAA records directly as if you’d typed them in manually. To the outside world it looks like a normal apex A record, so there’s no conflict with your SOA, NS, or MX.

There are two places this can happen. Provider-side flattening, which Cloudflare calls CNAME Flattening and AWS Route 53 implements as an ALIAS record, happens on the authoritative nameserver. The server is responsible for keeping the answer fresh, re-resolving the target on an interval and respecting its TTL. Resolver-side flattening would be messy and isn’t widely used, so nearly everything you’ll deploy today is authoritative. I’ve run both models in production, and the authoritative approach is far more predictable because you control refresh logic and you can still sign the final A record. That matters a lot if you’re also implementing DNSSEC Signing for CDN Infrastructure: Authenticated DNS Without the Performance Hit - a flattened apex response can be signed normally, while a raw CNAME at apex can’t.

; How a flattened apex looks on the authoritative server

; What YOU configure (pseudo-record, not exposed directly):
@   IN  ALIAS cdn.example.net.
@   IN  MX    10 mail.example.com.  ; Now legal, coexists with ALIAS

; What the resolver actually receives after flattening:
; Query: dig example.com A
@   IN  A     104.16.12.34
@   IN  A     104.16.13.34
@   IN  AAAA  2606:4700::6810:c22
; TTL is inherited from the target, typically 60-300s for CDNs

; Conceptual refresh logic inside the authoritative server:
; every TTL(target) seconds:
;   ips = resolve(cdn.example.net) // A + AAAA lookup
;   cache apex -> ips with min(TTL(target), flattening_TTL)

Flattening vs. ALIAS vs. Brute-Force A Records: What to Choose

If your CDN provider gives you a stable CNAME hostname like 12345.edge.cdn.net, you don’t want to hardcode the IPs it resolves to today. Those edge addresses change constantly as we add PoPs, drain nodes for maintenance, or shift traffic for capacity. I’ve seen teams dig the CDN hostname once, paste four A records at the apex, and then open a P1 six weeks later because half the edge in São Paulo was unreachable after a renumber. Flattening automates that follow-the-target step.

Performance is the other piece people get wrong. A flattened apex adds one extra lookup on the authoritative side, but it’s done asynchronously and cached, so the client resolver doesn’t pay for a double lookup on every query. In fact, when combined with EDNS Client Subnet for CDN Geolocation: Routing Users to the Nearest Edge, a good authoritative implementation will resolve the CDN target using the client's subnet so the returned IPs are still geo-targeted. The HTTP Working Group Specifications (https://httpwg.org/specs/) and web.dev Articles (https://web.dev/articles/) both emphasize that DNS latency directly impacts Time to First Byte, and flattening keeps that extra hop off the critical path.

Method Client Query Latency (p50) Failover After CDN IP Change Works With Apex MX/TXT/DNSSEC
Authoritative CNAME Flattening (Cloudflare-style) 11-18 ms 60-120s (target TTL) Yes - returns plain A/AAAA
ALIAS / ANAME Record (Route 53, DNSimple, NS1) 12-20 ms 60-300s (configurable) Yes - returns plain A/AAAA
Static A Records (Manual IP Paste) 9-14 ms Manual - hours to days (outage risk) Yes, but IPs go stale
Illegal CNAME at Apex Fail / SERVFAIL N/A - zone rejected No - breaks SOA/NS/MX

Putting CNAME Flattening Live: From Toggle to Traffic

Enabling flattening isn't a code deploy — it's a DNS behavior change, and you'll want to treat it like one. On Cloudflare, it's automatic and non-optional at the apex: any CNAME you create on example.com is flattened by default, returning A/AAAA records at query time with a 300-second TTL. On DNSimple, it's explicit via ALIAS records, and on AWS Route 53 you'll use an Alias record pointing to your CloudFront distribution or ALB, which resolves internally without ever publishing a CNAME. Don't just flip it and walk away. We've seen teams flatten cdn.example.com to an origin that itself returns a CNAME chain three deep — that's an extra 80-120ms of recursive lookup on every cache miss if your provider doesn't cache the flattened result aggressively.

Before you cut over, drop your apex TTL to 60 seconds at least 24 hours in advance. That gives you a fast rollback window. After enabling flattening, validate what resolvers actually see, not what your dashboard shows. Your authoritative UI will still say "CNAME," but the wire should show A records. If you're using flattening for failover, pair it with health checks — a flattened record that points to a dead IP is just a fast way to serve errors. For a deeper look at automated health-check-driven rerouting, see our guide on DNS Failover Automation for CDN: Automatic Rerouting When Origins Go Down.

A common gotcha: you can't have any other record types coexisting with a flattened apex that violate RFC rules. Your provider handles the CNAME conflict synthesis, but you still can't publish a CNAME and an MX on the same apex label and expect both to work naively. Most flattening providers synthesize the A record while preserving your MX, TXT, and NS records alongside it — but test it. A misconfigured SPF TXT record combined with a flattened apex has broken mail delivery for more than one high-traffic domain we've debugged.

# Verify what the world actually sees - not your dashboard
# 1. Query your authoritative server directly for the apex
dig @ns1.example-dns.com example.com A +short
# Expected with flattening: 104.21.12.34  # CDN Anycast IP, not a CNAME

# 2. Query a public resolver to confirm flattened TTL and synthesis
dig @1.1.1.1 example.com A +noall +answer
# example.com.    300   IN  A   104.21.12.34
# example.com.    300   IN  A   172.67.142.5

# 3. Confirm MX/TXT still coexist at apex (critical check)
dig example.com MX +short
# 10 mail.example.com.

Advanced Patterns: TTL Tuning, Monitoring, and Troubleshooting Loops

Once flattening's live, your biggest lever is TTL — and it's a tradeoff you'll tune constantly. A 60-second flattened TTL gives you sub-minute failover when your CDN rebalances PoPs, but it multiplies your query volume by 5-6x compared to a 300-second TTL. For a domain doing 50k queries per second at the edge, that's the difference between handling 10M and 50M authoritative hits per hour. We typically recommend 120-300 seconds for apex-to-CDN flattening; anything lower and you're paying for agility you don't need, since most CDNs don't rotate apex Anycast IPs more than once every few minutes. Go lower only if you're doing active-passive origin failover behind that flattened name.

When flattening breaks, it fails silently. The two patterns we see most: resolution loops and stale IP propagation. A loop happens when example.com flattens to origin.example.net, which CNAMEs back to example.com. Good providers detect loops and SERVFAIL after 8-10 hops, but cheap DNS proxies will just timeout, looking like packet loss. Stale IPs are subtler — your flattening provider cached the target's A record for 3600 seconds while the CDN already rotated it. Monitor this with synthetic checks from multiple vantage points every 30 seconds; alert if the resolved A record set doesn't match the CDN's published set for more than 2 minutes. And remember, flattened records don't protect you from volumetric abuse — if your apex is being used as a reflector, you'll need DNS Amplification Attack Mitigation: Protecting CDN DNS Infrastructure at the authoritative layer, not just clever CNAMEs.

If you need to inspect malicious domains without breaking flattening, don't blackhole at the apex. Use a dedicated sinkhole zone instead. We've found that mixing security policy directly into apex flattening logic creates un-debuggable edge cases where legitimate CDN IPs get sinkholed due to overlapping regular expressions. Keep your performance path (flattening) and your security path (DNS Sinkholing at CDN Scale: Redirecting Malicious Traffic for Analysis) on separate DNS labels or views — it'll save you a 3 AM incident call when a threat feed false-positives your own CDN hostname.

Frequently Asked Questions

Does CNAME flattening break my MX or TXT records at the apex?

No, if your provider does it correctly. True CNAME flattening and ALIAS records synthesize A/AAAA records at query time while leaving MX, TXT, and NS records intact at the apex. That's the whole point — it resolves the RFC 1912 conflict. But not all providers are equal. Test with dig MX and dig TXT after enabling it. If your provider returns only A records and drops your SPF or MX, switch providers.

What's the real performance cost of flattening vs. a direct A record?

For end users, effectively zero — they'll get an A record either way in ~15-40ms. The cost is on your authoritative infrastructure. The provider must recursively resolve your target (e.g., cdn.provider.net) every TTL interval. With a 300-second TTL, that's one extra lookup every 5 minutes per PoP, negligible. With a 60-second TTL across 200 PoPs, you're looking at 200 lookups/minute just to keep the flattened record fresh. It's cheap until you're doing it for 10,000 customer domains.

Can I flatten the apex to multiple CDN targets for load balancing?

You can, but don't chain CNAMEs to do it. Point your flattened apex directly to a load-balanced hostname that returns multiple A records, or better yet, use your DNS provider's native weighted or latency-based routing on top of the flattened record. Flattening a CNAME that itself resolves via DNS round-robin works, but you lose visibility into which IP is actually being served and troubleshooting becomes guesswork.

How is CNAME flattening different from ANAME or ALIAS records?

Functionally, they're the same to resolvers — all return synthesized A/AAAA records at the apex. The difference is standardization and implementation. CNAME flattening (Cloudflare's term) is proprietary behavior that happens automatically. ALIAS/ANAME are pseudo-record types implemented by DNSimple, DNS Made Easy, and others that you configure explicitly. Route 53's Alias is similar but only works for AWS resources. If you need provider portability, stick with a DNS provider that supports explicit ALIAS records rather than relying on automatic magic.

Related Articles

References & Standards: HTTP Working Group Specifications · web.dev Articles · IETF Datatracker