A records and CNAMEs are the two DNS record types that teams reach for most often, and the two that cause the most operational confusion when chosen incorrectly. An A record maps a hostname directly to an IPv4 address. A CNAME creates an alias that points to another hostname, which the resolver then follows to get the actual IP. Both produce the same final result for the browser: a numeric address to connect to. The difference is entirely in how that address is determined, and that difference matters more than it looks.
The choice between an A record and a CNAME affects CDN setup, SSL certificate issuance, email delivery, migration flexibility, and how your DNS configuration breaks when upstream infrastructure changes. Pick the wrong one at the zone apex, and your domain stops resolving. Pick the wrong one for an MX target, and inbound email silently fails. Pick the wrong one for a SaaS integration, and you inherit a maintenance burden every time the provider rotates IP addresses. This guide covers when each record type is the correct choice, where the RFC-level restrictions actually bite, and how to avoid the mistakes that cause production incidents.
Quick check: Use the DNS Lookup Tool to see what record types currently exist for any hostname, then review changes over time with DNS History.
A Records: Direct IP Mapping
An A record is the simplest record in DNS. It answers one question: what IPv4 address should this hostname resolve to? When a resolver queries `example.com` and receives an A record pointing to `93.184.216.34`, the conversation is over. There is no indirection, no chain to follow, no dependency on another hostname's resolution. The resolver has the IP and the client can open a connection.
The IPv6 equivalent is the AAAA record (sometimes called a quad-A record). It works identically but returns a 128-bit IPv6 address instead of a 32-bit IPv4 address. Most production domains publish both A and AAAA records for dual-stack connectivity. The choice between A and AAAA is not an either-or decision; you typically want both. The choice that matters operationally is whether to use an A record or a CNAME at a given hostname.
A records are the right choice in several clear situations. First, when you are configuring the zone apex (the bare domain like `example.com` without any subdomain prefix), an A record is often the only standards-compliant option. Second, when you control the IP address directly and it is unlikely to change, such as a static server or an elastic IP attached to your own infrastructure, A records give you a clean, single-hop resolution. Third, when you need other record types at the same hostname, such as MX records for email or TXT records for SPF and domain verification, A records are required because CNAMEs cannot coexist with any other record type at the same name.
$ dig example.com A +short
93.184.216.34
$ dig example.com AAAA +short
2606:2800:220:1:248:1893:25c8:1946
The limitation of A records is that they encode a specific IP address. If the upstream server moves to a new address, every A record pointing to the old one must be updated. For a single domain this is manageable. For dozens of subdomains all pointing to the same infrastructure, it becomes a coordination problem that CNAMEs were designed to solve.
CNAME Records: Aliasing to Another Hostname
A CNAME record does not contain an IP address. It contains another hostname. When a resolver encounters a CNAME, it restarts the lookup process using the target hostname, following the chain until it reaches an A or AAAA record that provides the actual IP. The CNAME at `blog.example.com` might point to `example.github.io`, and the resolver then looks up the A record for `example.github.io` to get the final address.
This indirection is the core advantage. If the provider behind `example.github.io` changes its IP addresses, every domain that CNAMEs to it automatically picks up the new address on the next lookup, without any DNS changes on the customer side. This is why virtually every CDN, SaaS platform, and cloud load balancer integration asks you to create a CNAME. The provider retains control of the IP mapping and can rotate, scale, or migrate infrastructure without requiring coordinated DNS updates from thousands of customers.
$ dig blog.example.com CNAME +short
example.github.io.
$ dig example.github.io A +short
185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153
The trade-off is that every CNAME adds a resolution step. The resolver must follow the alias before it can return an IP. In practice, this adds a few milliseconds at most because resolvers cache aggressively. But CNAME chains (a CNAME pointing to another CNAME pointing to yet another CNAME) compound the latency and create fragile dependency graphs. Most resolvers cap chain depth at 8 to 16 hops and return SERVFAIL if the chain is too long. Keeping CNAME chains to one or two hops is a best practice that avoids both performance issues and debugging nightmares.
The harder constraint is the exclusivity rule. RFC 1034 states that if a CNAME record exists at a given name, no other record type may exist at that same name. You cannot have a CNAME and an MX record at `shop.example.com`. You cannot have a CNAME and a TXT record. You cannot have a CNAME and an NS record. This rule exists because the CNAME is supposed to be a complete alias: all queries for that name, regardless of type, are redirected to the canonical name. Allowing other records alongside the CNAME would create ambiguity about which answer is authoritative.
The Zone Apex Problem
The zone apex is the bare domain itself: `example.com`, not `www.example.com` or `api.example.com`. According to RFC 1034, you cannot place a CNAME at the zone apex. The reason connects directly to the exclusivity rule. The zone apex must have SOA and NS records (these are required for the zone to function at all). Since a CNAME cannot coexist with other record types, a CNAME at the apex would conflict with the mandatory SOA and NS records. The zone would be technically invalid.
This creates a real operational problem. Many modern hosting platforms only provide a hostname for routing, not a stable IP address. AWS Elastic Load Balancers, for example, return a hostname like `my-lb-123456.us-east-1.elb.amazonaws.com` that resolves to different IPs over time as AWS scales the load balancer. If your apex domain needs to point at that load balancer, a CNAME would be the natural choice, but the RFC says you cannot use one there.
The industry has converged on a workaround: synthetic record types that behave like CNAMEs at the DNS provider level but return A or AAAA records to the querying resolver. Cloudflare calls this CNAME flattening and does it automatically for any CNAME at the apex. Route 53 offers ALIAS records. DNSimple and NS1 support ANAME records. The mechanism is the same in all cases: the authoritative nameserver resolves the CNAME target internally and returns the resulting IP address as a plain A record, so the resolver never sees the CNAME indirection and the zone remains RFC-compliant.
- Cloudflare: automatic CNAME flattening at the apex, optional for subdomains.
- AWS Route 53: ALIAS record type that targets ELB, CloudFront, S3, and other AWS resources.
- DNSimple and NS1: ANAME records that resolve the target at query time and return A/AAAA answers.
- If your DNS provider does not support flattening, the apex must use A records pointing to known IPs.
The practical consequence is that your DNS provider choice constrains your apex domain options. If you need to point your bare domain at a service that only provides a hostname, you need a provider that supports ALIAS, ANAME, or CNAME flattening. Otherwise, you are stuck hardcoding IP addresses in A records and accepting the maintenance burden when those IPs change.
Decision Matrix: When to Use A vs CNAME
The decision between an A record and a CNAME comes down to four factors: whether the hostname is the zone apex, whether you control the target IP, whether other record types need to coexist at the same name, and how much operational flexibility you need when upstream infrastructure changes. The following breakdown covers the most common scenarios.
- Zone apex (example.com): Use an A record or an ALIAS/ANAME if your provider supports it. A CNAME is prohibited by RFC 1034.
- www subdomain pointing to a CDN or hosting provider: Use a CNAME to the provider's hostname. This lets the provider manage IP rotation without requiring your intervention.
- Subdomain for a SaaS integration (shop.example.com to platform.shopify.com): Use a CNAME. The SaaS provider controls the IP space and will change addresses during scaling events.
- Subdomain that also needs MX or TXT records: Use an A record. The CNAME exclusivity rule prevents any other record types from coexisting with a CNAME at the same name.
- Static server with a stable elastic IP: Use an A record. There is no indirection benefit when the IP is under your control and unlikely to change.
- Load balancer with a provider-assigned hostname: Use a CNAME for subdomains. For the apex, use ALIAS/ANAME or configure the provider to give you a static IP.
- Email domain (MX target): The hostname in the MX record's right-hand side must resolve via A or AAAA records, never via a CNAME. RFC 2181 and RFC 5321 are explicit about this.
- Internal service discovery: Use A records when stability matters or CNAME when you want the flexibility to remap service endpoints without redeploying configuration.
The general principle is: use a CNAME when you want to delegate IP management to someone else, and use an A record when you need direct control or when DNS constraints (apex, MX, coexisting records) prohibit a CNAME. When in doubt, a DNS Lookup of the hostname reveals what is currently published, and Domain Health flags common misconfigurations.
Common Mistakes and How They Break Things
Most A-record-vs-CNAME incidents are not caused by teams picking the wrong type out of ignorance. They are caused by changes that were valid when made but became invalid after another change happened elsewhere in the zone. A CNAME is added for a subdomain, and weeks later someone adds a TXT record for domain verification at the same name, silently overwriting the CNAME or creating a conflicting state depending on the provider. The following mistakes appear repeatedly in production DNS investigations.
- CNAME at the zone apex: Some DNS providers allow this and silently flatten it. Others reject it. Others accept it and serve broken responses. If your bare domain stops resolving, check for an invalid apex CNAME first.
- CNAME where MX or TXT records are needed: Adding a CNAME to a name that previously had MX records silently breaks inbound email. SPF and DKIM TXT records at the same name also disappear or conflict.
- Long CNAME chains: A CNAME pointing to a CNAME pointing to another CNAME adds latency and failure points. If any link in the chain returns NXDOMAIN or times out, the entire resolution fails.
- Dangling CNAMEs pointing to deprovisioned services: When you delete a cloud resource but leave the CNAME in place, anyone who registers the orphaned target hostname can serve content on your subdomain. This is the subdomain takeover attack vector.
- A records with stale IPs after a migration: Teams migrate infrastructure and update the primary hostname but forget that five other A records pointed to the old IP. Traffic silently goes to the wrong server or fails entirely.
- Mixing A and CNAME at the same name: This is invalid per RFC 1034. Some providers reject it cleanly; others create undefined behavior where the response depends on query order or caching state.
Reading A and CNAME Records in dig Output
The `dig` command is the standard tool for inspecting DNS records from the command line. Understanding its output for A and CNAME records makes it easier to diagnose resolution issues, verify configurations, and confirm that changes have propagated. Here is what a typical A record query looks like.
$ dig example.com A
;; QUESTION SECTION:
;example.com. IN A
;; ANSWER SECTION:
example.com. 86400 IN A 93.184.216.34
;; Query time: 12 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
The answer section shows the hostname, the TTL in seconds (86400 means the resolver can cache this answer for 24 hours), the record class (IN for internet), the record type (A), and the IPv4 address. A straightforward, single-hop resolution. Now compare that with a hostname that uses a CNAME.
$ dig www.example.com A
;; QUESTION SECTION:
;www.example.com. IN A
;; ANSWER SECTION:
www.example.com. 3600 IN CNAME cdn.provider.net.
cdn.provider.net. 60 IN A 203.0.113.50
cdn.provider.net. 60 IN A 203.0.113.51
;; Query time: 24 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
The answer section now contains two stages. First, the resolver shows that `www.example.com` is a CNAME pointing to `cdn.provider.net`. Then it shows the A records for the CNAME target. Notice the different TTL values: the CNAME has a 3600-second TTL while the A records behind it have only 60 seconds. This is common with CDN providers who rotate IPs frequently. The effective cache lifetime for the full resolution is the minimum of the two TTLs, meaning the client will re-query within 60 seconds even though the CNAME itself could be cached for an hour.
When debugging, the `+trace` flag in dig shows the full delegation chain from the root servers down to the authoritative answer. This is particularly useful when a CNAME points across zone boundaries and you need to identify which nameserver in the chain is returning an unexpected result.
$ dig www.example.com A +trace
;; Received from root server -> com. TLD -> example.com NS
;; -> CNAME www.example.com -> cdn.provider.net
;; -> Received from provider.net NS -> A 203.0.113.50
A Record vs CNAME in the Broader DNS Picture
The A-vs-CNAME decision is one piece of a larger DNS configuration that includes MX records for email routing, TXT records for SPF, DKIM, and DMARC policies, NS records for delegation, and CAA records for certificate issuance control. These record types interact. An MX record that points to a hostname which only has a CNAME will cause delivery failures with strict mail servers. A CAA record that permits certificate issuance for your domain does not apply to a CNAME target hosted in a different zone. Understanding these interactions prevents the class of DNS incidents where each record looks correct in isolation but the combination produces broken behavior.
Point-in-time lookups answer what a record resolves to right now. But DNS configuration is a moving target: records change during migrations, providers rotate IPs behind CNAMEs, and stale records accumulate as projects are decommissioned. Comparing current records against historical DNS data turns a single data point into a trend that reveals drift, identifies orphaned records, and surfaces changes that were made without corresponding infrastructure updates.
Whether you are setting up a new subdomain, migrating a CDN, debugging email delivery, or auditing your zone for dangling records, the A-vs-CNAME choice is the first decision in a chain of DNS decisions that determine how your domain behaves in production. Getting it right at the start avoids a category of incidents that are easy to prevent and tedious to diagnose after the fact.
Independent references: Review RFC 1035 for the original A record and CNAME specification, and the Cloudflare DNS record types reference for practical guidance on record type selection and provider-specific behavior.