Choosing DNS records: A vs AAAA vs CNAME vs ALIAS vs TXT vs MX, and the apex CNAME problem
Operating a domain inevitably means writing DNS records — pointing apex to a CDN, delegating subdomains, configuring email. Picking the wrong record type breaks DNS, breaks email, or breaks the CDN integration. This article walks through the practical decisions and the well-known apex CNAME problem with its workarounds.
The six core types
| Record | Role | Example value |
|---|---|---|
| A | name → IPv4 | 203.0.113.42 |
| AAAA | name → IPv6 | 2001:db8::1 |
| CNAME | name → another name | target.example.net. |
| TXT | name → arbitrary string | "v=spf1 include:..." |
| MX | mail server | 10 mail.example.com. |
| SRV | service host + port | 0 5 5060 sip.example.com. |
Plus provider-specific ALIAS / ANAME (covered below), NS (delegation), and CAA (certificate authority restrictions).
A vs AAAA: IPv4 and IPv6
The fundamental “name to IP” record:
example.com. IN A 203.0.113.42
example.com. IN AAAA 2001:db8::1 Modern best practice is to set both. IPv6-aware resolvers (Google Public DNS, Cloudflare DNS) try AAAA first, falling back to A.
Happy Eyeballs
Browsers implement Happy Eyeballs (RFC 8305) — connect to A and AAAA in parallel and use whichever responds first. Broken IPv6 paths don’t visibly hurt users.
But if your AAAA path is intermittently slow, users feel intermittent latency. Both records require both paths to actually work well.
CNAME: alias to another name
www.example.com. IN CNAME example.com. Resolvers find the CNAME, then resolve the target’s A/AAAA records. Common uses:
www.example.com → example.com(redundant www).app.example.com → cname.vercel-dns.com.(CDN/hosting service).assets.example.com → s3-website.amazonaws.com.(AWS S3 static).
CNAME exclusivity
A name with a CNAME can have no other records:
foo.example.com. IN CNAME bar.example.net.
foo.example.com. IN TXT "info" ← ✗ CNAME and other types can't coexist This is RFC 1034 §3.6.2. Putting a CNAME on a subdomain delegates that subdomain entirely.
The apex CNAME problem
The most-common DNS gotcha: you can’t put a CNAME on the apex (root domain):
example.com. IN CNAME cname.vercel-dns.com. ← ✗ RFC violation The apex requires NS records (authoritative DNS pointers) and an SOA record (zone administrative info), and the CNAME-exclusivity rule forbids coexistence.
Where CNAME is allowed:
| Place | CNAME OK? |
|---|---|
www.example.com | ✓ |
api.example.com | ✓ |
example.com (apex) | ✗ |
*.example.com (wildcard) | ✓ |
Workaround 1: A record with a fixed IP
Use an A record at the apex:
example.com. IN A 76.76.21.21 Problem: CDN IPs can change. Hardcoding IPs is fragile but Vercel, Netlify, Cloudflare Pages publish stable apex IPs to make this practical.
Workaround 2: ALIAS / ANAME / flattening
Provider-specific “pseudo CNAME” features:
- Cloudflare: CNAME Flattening (apex CNAME accepted, internally resolved to A).
- Route 53: ALIAS (AWS-internal optimization).
- DNSimple / Dynadot: ALIAS / ANAME (general).
- Vercel: recommends
A 76.76.21.21for apex (their stable IP).
example.com. IN ALIAS cname.vercel-dns.com. ← provider syntax ALIAS-style records have the DNS provider resolve the target dynamically and return the IPs as A records. Not standardized, so migrating providers means rewriting.
Workaround 3: apex redirect
Don’t put the CDN at apex. Instead, route apex to a tiny HTTP redirect server that 301s to www.example.com:
example.com. IN A 203.0.113.42 ← simple HTTP redirector
www.example.com. IN CNAME cname.vercel-dns.com. Old-school but still in production at many sites.
TXT: arbitrary string metadata
example.com. IN TXT "v=spf1 include:_spf.google.com ~all"
example.com. IN TXT "google-site-verification=abc..." Common uses:
| Purpose | Format |
|---|---|
| SPF (mail-sender authentication) | v=spf1 include:... ~all |
| DKIM (mail signing key) | v=DKIM1; k=rsa; p=... (under <selector>._domainkey.) |
| DMARC (mail policy) | v=DMARC1; p=reject; (under _dmarc.) |
| Domain verification | google-site-verification=..., stripe-verification=... |
| Let’s Encrypt DNS-01 challenge | _acme-challenge.example.com TXT |
TXT records are stackable. Single values are limited to 255 characters but can be multi-string concatenated:
example.com. IN TXT "first-part" "second-part" MX: mail destination
example.com. IN MX 10 mail.example.com.
example.com. IN MX 20 backup.example.com. The 10 / 20 is priority — lower wins. Senders try the lowest-priority server first, fall back on failure.
Required for any mail-receiving domain. Google Workspace uses 1 ASPMX.L.GOOGLE.COM.; Microsoft 365 uses 0 example-com.mail.protection.outlook.com..
SRV: service discovery
_sip._tcp.example.com. IN SRV 0 5 5060 sip.example.com. _<service>._<protocol> names define service host + port dynamically. Microsoft AD, SIP, XMPP. Rarely seen in web service operations.
Decision flow for new records
When adding records:
- Need email? → MX first.
- Static site / CDN at apex? → ALIAS (provider-specific) or apex redirect via
www. - Delegate a subdomain to a service? → CNAME.
- Verification, SPF, DMARC? → TXT.
- Want IPv6? → both A and AAAA.
- Restrict cert issuance? → CAA.
TTL strategy
| Record stability | Recommended TTL |
|---|---|
| Stable (A/AAAA/NS) | 86400 (1 day) – 604800 (1 week) |
| Behind a load balancer, changes expected | 60–300 |
| Migration / experimentation | 60 |
The standard migration trick: lower TTL ≥1 day before the change, then change, then restore TTL after propagation completes. This shortens the cache window during cutover.
Pitfalls
1. Deep CNAME chains
a.example.com → b.example.net → c.example.org → 203.0.113.42
Resolvers do recursive resolution, so deep chains add latency and timeout risk. Keep CNAME hops to 3 or fewer.
2. Confusing NS with CNAME
For “let another DNS provider manage this subdomain,” use NS records (delegation), not CNAME:
sub.example.com. IN NS ns1.other-provider.com.
sub.example.com. IN NS ns2.other-provider.com. CNAME means “name → another name.” NS means “this subtree is authoritatively served by another nameserver.” Substituting CNAME for NS prevents per-subdomain configuration.
3. Negative caching of NXDOMAIN
Queries for non-existent records get negatively cached. Testing immediately after creating a record may hit a cached “doesn’t exist” entry.
For new domains, query the authoritative servers directly with dig +trace example.com rather than relying on resolver cache.
Summary
A, AAAA, CNAME, TXT, MX cover ~95% of day-to-day DNS work. Master the apex CNAME constraint and TTL planning and you avoid most operational pain. ALIAS / ANAME are provider-specific and add lock-in. New projects should set both A and AAAA, plus a CAA record, for modern DNS hygiene.
For inspecting IP address ranges and formats, the IP address tool covers the standard cases.