skip to content

Hosted Zones & Record Types

How Route 53 stores your DNS: public and private hosted zones, the records inside them, and the alias record that lets a zone apex point at an ELB or CloudFront. The apex-CNAME problem is the classic setup question here.

part ofAWSoverview, primer and where to startread it →
on this pageshow

questions

4

In Route 53, why can't you point the zone apex example.com at an Application Load Balancer with a CNAME record, and what do you use instead?

level: middleimportance: must knowfreq 76%

answer

  1. a CNAME can own nothing else
  2. the apex already owns SOA and NS
  3. Route 53 has its own record type
  4. stored as type A, resolved internally
  5. target's hosted zone ID, not yours

basics

~20 s

DNS forbids a CNAME at a zone apex, which must also hold SOA and NS records. Route 53's alias record is an A record whose target is an AWS resource, so the apex can point at a load balancer and still return plain addresses.

solid answer

~50 s

A CNAME cannot live at a zone apex: in DNS, a name that owns a CNAME can own nothing else, and the apex must own its SOA and NS records — so Route 53 rejects the change outright. An ALB also has no stable addresses, so pinning today's IPs into an A record breaks as soon as AWS scales or replaces nodes. The fix is a Route 53 **alias** record: an A (or AAAA) record whose `AliasTarget` carries the load balancer's DNS name plus the load balancer's own hosted zone ID (`CanonicalHostedZoneId`, not your zone's ID). Route 53 resolves the target internally and hands the client an ordinary A response. Aliases to AWS resources have no TTL you can set — the target's TTL applies — and queries answered from them are not billed. Below the apex, a normal CNAME is still the right tool for external names.

code

bash · 4 lines
bash
aws elbv2 describe-load-balancers \
  --names my-alb \
  --query 'LoadBalancers[0].[DNSName,CanonicalHostedZoneId]' \
  --output text

go deeper

for a junior

Recall that example.com is the zone apex and cannot hold a CNAME, and say you would create an A record of type alias pointing at the load balancer.

for a middle

Explain the mechanism: a CNAME may not coexist with the apex's mandatory SOA and NS records, and Route 53 resolves an alias target internally so the client gets a plain A answer.

for a senior

Show the operational consequences — AWS owns the TTL on an AWS-target alias, alias queries to AWS resources are not billed, and hardcoded ALB addresses fail silently when the fleet scales.

for a principal

Own it as a standard: mandate alias at the apex across accounts, and weigh the portability cost, since alias is Route 53-only and is the one record a provider migration cannot copy verbatim.

## The rule that creates the problem DNS defines a CNAME as an alias for an entire name: if a name owns a CNAME record, it must own no other record type. A zone apex — the bare domain, `example.com` — is required to own an SOA record and a set of NS records, because those are what make it a zone at all. The two rules collide, so a CNAME at the apex is illegal in DNS itself, not just in AWS. Route 53 enforces it at the API: a change batch that puts a CNAME on the apex comes back as an `InvalidChangeBatch` error rather than silently misbehaving later. This is the single most common Route 53 setup question because it is exactly what you hit on day one: you have an Application Load Balancer, AWS gave you a name like `my-alb-1234567890.us-east-1.elb.amazonaws.com`, and you want `example.com` to reach it. ## Why an A record with IPs is not the escape hatch The obvious workaround is to resolve the load balancer's name once and paste the addresses into an A record. Don't. An ALB is a managed fleet: AWS adds and removes nodes per Availability Zone as traffic changes, and the addresses behind its DNS name rotate. A hardcoded A record works in staging and then blackholes production weeks later when the node it named is gone. The same reasoning applies to CloudFront and to API Gateway — you are given a name, never a contract about addresses. ## The alias record Route 53's alias record is a Route 53-specific extension stored in the zone. It has a `Type` of `A` or `AAAA` and, instead of a value, an `AliasTarget` object with three fields: ```json "AliasTarget": { "HostedZoneId": "Z35SXDOTRQ7X7K", "DNSName": "my-alb-1234567890.us-east-1.elb.amazonaws.com.", "EvaluateTargetHealth": false } ``` The `HostedZoneId` here is the *target's* zone ID, not the zone you are editing — this trips people up constantly. For an ALB or NLB it is the load balancer's `CanonicalHostedZoneId` (readable from `aws elbv2 describe-load-balancers`); for CloudFront it is the fixed global value `Z2FDTNDATAQYW2`; for an S3 website endpoint or an API Gateway custom domain it is a per-region value AWS publishes. At query time Route 53 looks the target up internally and answers with the target's current addresses as an ordinary A record. The resolver and the browser never see an alias — there is no extra hop, no second lookup, and nothing for an old client to fail to understand. That is the practical difference from a CNAME, which costs the resolver another round trip to follow. Alias targets are a fixed menu of AWS resources: CloudFront distributions, ELBs, S3 website endpoints, API Gateway custom domains, VPC interface endpoints, Global Accelerator, Elastic Beanstalk environments, and another record in the same hosted zone. You cannot alias to an arbitrary hostname somewhere else on the internet — that case still needs a CNAME, below the apex. ## TTL and billing An alias to an AWS resource has no TTL field you can set. Route 53 uses the target's TTL; for ELB targets that is 60 seconds. This is a feature, not a limitation — AWS controls how long clients cache addresses for infrastructure whose addresses AWS controls. (For an alias that points at another record in the same hosted zone, that record's own TTL applies.) Billing differs too: queries answered by an alias record pointing at an AWS resource are free, while queries answered by a CNAME or a plain A record are charged per million. On a busy apex that is a real, if small, line item. ## What still deserves a CNAME Use a CNAME when the target is not an AWS alias target — a SaaS vendor's hostname for `status.example.com`, the record ACM asks you to publish for DNS domain validation, or a partner-hosted subdomain. None of those sit at the apex, so the rule never bites. ## The portability caveat worth saying out loud Alias is a Route 53 feature. Other DNS providers solve the apex problem with their own synthetic record types, and the names and semantics differ. If your DNS strategy allows for moving providers, the apex is the record that will not port cleanly — worth knowing before you promise a migration is a zone-file copy.

  • If the alias record has no TTL field, how long do clients cache the answer?
    Route 53 applies the target's TTL. For ELB aliases that is 60 seconds, and AWS owns that value — you cannot raise or lower it. An alias that points at another record inside the same hosted zone is the exception: it inherits that record's TTL, which you do control.
  • Someone put the wrong value in the alias target's HostedZoneId and the change was accepted. What went wrong?
    They almost certainly used their own hosted zone's ID. That field identifies the target's zone — the load balancer's `CanonicalHostedZoneId`, or `Z2FDTNDATAQYW2` for any CloudFront distribution. Route 53 validates that the ID and DNS name form a real target, so a mismatched pair is normally rejected; a pair that is internally consistent but wrong points traffic somewhere you did not intend.
  • Does using an alias record instead of a CNAME change anything for the client?
    No — that's the point. Route 53 resolves the target itself and returns an ordinary A or AAAA answer, so the client sees addresses, not a chain to follow. A CNAME forces the resolver into an additional lookup before it gets an address, which costs a little latency on a cold cache.

saying these in an interview costs you the question

  • Says you can just create a CNAME at the apex
  • Pastes the load balancer's current IPs into an A record
  • Uses your own zone's ID as the alias target hosted zone ID
  • Claims you can set a custom TTL on an AWS-target alias
  • Thinks an alias can point at any external hostname

context

open as a page

You created a public hosted zone for example.com in Route 53 and added an A record for www, but the name still does not resolve anywhere on the internet. What step is most likely missing, and where is it performed?

level: juniorimportance: should knowfreq 56%

basics

~20 s

Delegation. A new Route 53 public hosted zone is assigned four name servers, and nothing on the internet consults them until the domain's registrar publishes those four as the domain's NS records. Records exist but are unreachable until then.

open as a page

After you create a Route 53 private hosted zone named example.com and associate it with a VPC, instances in that VPC stop resolving public example.com names such as www.example.com. What is happening, and how do you fix it?

level: seniorimportance: should knowfreq 48%

basics

~20 s

The private hosted zone becomes authoritative for the whole example.com namespace inside that VPC. Route 53 Resolver answers from it and returns NXDOMAIN for names it does not contain — it never falls back to public DNS. Scope the private zone to a dedicated internal subdomain instead.

open as a page

An on-premises data center is connected to a VPC over Direct Connect. On-prem servers must resolve names held in a Route 53 private hosted zone, and EC2 instances must resolve internal on-prem names. Which Route 53 Resolver components do you configure in each direction?

level: seniorimportance: nice to knowfreq 34%

basics

~20 s

Route 53 Resolver endpoints, one per direction. An inbound endpoint lets on-premises servers forward queries into the VPC to reach private hosted zones. An outbound endpoint, plus forwarding rules naming the on-prem domains and target IPs, sends VPC queries to the on-prem resolvers.

open as a page