What does a CNAME actually do?
CNAME is record type 5, defined in RFC 1034/1035. The name is short for "canonical name": the record says *this name is not the real one; the canonical name is over there*. When a resolver looks up www.github.com and finds a CNAME to github.com, it does not return an address — it restarts the query for github.com and returns both the CNAME and the resulting A and AAAA records in the answer section.
This is a genuine redirection at the name level, not a pointer that only applies to address queries. A query for MX at a CNAMEd name gets redirected to the target too, which is exactly why a CNAME cannot sit alongside an MX record — the alias would have swallowed it.
The value CNAMEs provide is indirection you do not have to maintain. If a vendor gives you myapp.somehost.net and you CNAME app.example.com to it, the vendor can rotate their addresses freely and your zone never changes. Point an A record at their IP instead and you have taken on the job of tracking their infrastructure. The tradeoff is covered in depth in CNAME vs A record.
CNAME syntax and fields
| Field | Example | Meaning |
|---|---|---|
| Name (owner) | www.github.com. | The alias. Must not be the zone apex, and must have no other records. |
| TTL | 3563 | Cache lifetime of the alias itself. Independent of the target's TTL. |
| Class | IN | Internet class. |
| Type | CNAME | Record type 5. |
| RDATA | github.com. | Exactly one fully qualified target hostname. Never an IP address, never a URL, never a list. |
github.com without the dot is relative and expands to github.com.example.com.. Most provider web forms add the dot for you — but if you are editing BIND zone files or a .tf DNS resource by hand, the missing dot is the classic outage.Why you cannot put a CNAME at the apex
The zone apex — example.com with no label in front — must carry an SOA record and its NS records. A CNAME may not coexist with other data at the same name. Therefore the apex cannot be a CNAME. This is not a limitation of your DNS provider; it is a structural rule of the protocol, and a nameserver that lets you do it is producing a zone that resolvers will treat as broken.
The workarounds fall into two categories:
- Provider-side flattening. ALIAS records, ANAME records, and Cloudflare's CNAME flattening all work the same way: the authoritative server resolves the target itself and returns synthesized A/AAAA records for the apex. The wire protocol sees plain address records, so it is fully compliant. The cost is that resolution now depends on your DNS provider tracking the target, and TTLs are provider-controlled.
- Redirect at HTTP instead. Put A/AAAA records at the apex pointing at something cheap that issues a 301 to
www, and CNAMEwwwto the platform. Simple, but adds a round trip and does not help non-HTTP services.
ALIAS/ANAME are not standardized and behave differently per provider, so read your provider's current documentation rather than assuming portability between them.
CNAME cannot coexist with other records
This is the rule that generates the most support tickets. If mail.example.com is a CNAME, it cannot also have a TXT record, an A record, or an MX record. Concretely:
- You cannot add a domain-verification TXT record to a hostname that is already a CNAME. Put the TXT at a different label, or at the apex.
- You cannot CNAME a hostname you also want to serve MX from. An MX record's *target* also must not be a CNAME (see the MX reference).
- DKIM is the exception that proves the rule:
selector._domainkey.example.comis frequently a CNAME (Microsoft 365 does this), and that works because nothing else needs to live at that exact name. - DNSSEC is a documented exception in the other direction — RRSIG and NSEC records legitimately appear beside a CNAME because they sign it.
When a provider UI refuses to save a record with a vague error, a pre-existing CNAME at the same host is the first thing to check. Query the name with TXT lookup or the full DNS Lookup to see everything that is already there.
Chains, and what they cost
A CNAME may point at another CNAME. Resolvers follow the chain, but every hop is an extra resolution step, and each link has its own TTL — the effective freshness of the whole chain is governed by the shortest link, while the total latency of a cold lookup is the sum of the hops.
- Latency. Each uncached hop is another round trip, sometimes to a different provider on a different continent. Three-hop chains through a CDN and a vendor add real milliseconds to first connection.
- Resolver limits. Recursive resolvers cap chain length (commonly around 8–16 hops depending on implementation) and will return SERVFAIL beyond it. Loops are detected and fail the same way.
- Debuggability. When a chain crosses three vendors, working out which link broke is genuinely painful.
dig +traceand querying each hop individually is the only reliable method. - Fragility. Any link going NXDOMAIN takes the whole name down. You have taken a dependency on every intermediate operator.
One hop is normal and good. Two is usually acceptable when a vendor requires it. Three or more deserves a conversation.
TTL guidance for CNAMEs
A CNAME rarely changes once set — it is the *target* that moves, and that is the vendor's problem. So the alias itself can carry a comfortable TTL of 3600 or more. The exception is a cutover where you are moving app.example.com from one vendor to another: lower the CNAME TTL to 300 a day or two before, switch, verify, then raise it again. Remember that the target's own A record TTL applies independently and you do not control it.
Common CNAME mistakes
- CNAME at the apex. Covered above. Use ALIAS/flattening or A records.
- Pointing a CNAME at an IP address. The RDATA is a name.
CNAME 203.0.113.10is invalid; you wanted an A record. - Pointing a CNAME at a URL. DNS has no concept of paths, schemes, or ports. If you need
example.com/blogto go somewhere, that is an HTTP redirect, not DNS. - Missing trailing dot in a hand-edited zone. Produces
target.example.com.example.comand an instant NXDOMAIN. - CNAME as an MX target. Prohibited by RFC 2181; some senders tolerate it, plenty do not. Point MX at a name with real address records.
- Adding a TXT beside an existing CNAME. Rejected, or worse, silently accepted and then ignored by resolvers.
- Leaving a CNAME pointing at a deleted vendor resource. A dangling CNAME to a decommissioned cloud hostname is a subdomain-takeover risk — someone else can claim that hostname on the same platform and serve content on your subdomain. Audit and delete unused aliases.
Check it with dig
# The alias target only
dig +short www.github.com CNAME
# Full answer — shows the CNAME and the addresses it resolved to
dig +noall +answer www.github.com A
# Walk a chain hop by hop
dig +short app.example.com CNAME
dig +short <target-from-above> CNAME
# See the whole delegation and chain
dig +trace www.wikipedia.org
# Confirm nothing else exists at the alias name (should be empty)
dig +short www.github.com TXTIf a CNAME resolves from the authoritative server but not from a public resolver, you are waiting on cache expiry — check across resolvers with DNS Compare or the propagation checker.