Route 53 records, alias targets and change batches
What an alias record is and how it differs from a CNAME (apex, targets, TTL, pricing, record type), which AWS resources it can target, how ChangeResourceRecordSets batches work (CREATE, UPSERT, DELETE, all-or-nothing, PENDING to INSYNC), and the API errors with their fixes.
markdownreferencev45HK2-FMTDstage: referencetrust: officialservice: route53interface: anyalias recordCNAMEzone apexalias targetsAliasTargetEvaluateTargetHealthChangeResourceRecordSetschange batchUPSERTCREATEDELETEGetChangePENDINGINSYNCInvalidChangeBatchInvalidInputNoSuchHostedZoneNoSuchHealthCheckPriorRequestNotCompleteweighted record weight 0-255
Point names at AWS resources with alias records. Change records in batches that apply completely or not at all. A change is live on Route 53's name servers once GetChange reports INSYNC.
Alias vs CNAME
| Alias | CNAME | |
|---|---|---|
At the zone apex (example.com) | Yes (except to a CNAME record in the same zone) | Never, in any hosted zone |
| Targets | Selected AWS resources, or another record of the same type in the same zone | Any DNS name, anywhere |
| Answers | Only when the query's name and type match (an A alias answers A queries) | All query types for the name |
| TTL | Not settable: the target resource's default, or the target record's TTL | You set it |
| Query charges | None for aliases to AWS resources | Charged. Twice when it points at another Route 53 record |
In dig | Shows as the record type (A, AAAA) | Shows as CNAME |
| Follows target IP changes | Yes, automatically | Through normal DNS |
Alias targets
API Gateway custom domains (Regional or edge-optimized), VPC interface endpoints, CloudFront distributions, App Runner services, Elastic Beanstalk environments, Elastic Load Balancing (ALB, NLB, Classic), Global Accelerator, OpenSearch Service custom domains, S3 buckets configured as static websites, AppSync domain names, and other records in the same hosted zone.
An S3 website alias requires the bucket name to equal the record name (for example acme.example.com). It routes to the website endpoint, over HTTP only (UNVERIFIED in the collected sources; the page shows the matching-name example).
Change batches
ChangeBatch.Changes[]withActionset toCREATE(fails if the record exists),UPSERT(create or update) orDELETE(every value must match the existing record exactly).- Transactional: Route 53 validates the whole batch and applies all changes or none. A DELETE plus a CREATE of the same name swaps a record with no gap.
- Deleting the same record twice in one batch is an
InvalidChangeBatch. - Alias records carry
AliasTarget { HostedZoneId, DNSName, EvaluateTargetHealth }. HereHostedZoneIdis the target resource's zone ID, not yours. - Routing-policy fields:
SetIdentifier, plus one ofWeight(0–255),Region(latency),Failover(PRIMARY/SECONDARY),GeoLocation,GeoProximityLocation,CidrRoutingConfigorMultiValueAnswer, and optionallyHealthCheckId. - Request size limits are on the Route 53 quotas page (not collected; don't assume).
Propagation
The response's ChangeInfo.Status is PENDING. Poll GetChange with ChangeInfo.Id until it reports INSYNC, which generally takes under 60 seconds. After that, resolvers still serve cached answers until their TTL expires. Name-server delegation changes at the registrar take 24–48 hours to settle.
Errors (ChangeResourceRecordSets)
| Error | HTTP | Cause → fix | Check |
|---|---|---|---|
InvalidChangeBatch | 400 | One or more changes are invalid. The exception carries a list of messages, one per problem: a CREATE of an existing record, a DELETE whose values don't match, a CNAME at the apex, a wrong alias target zone ID, a duplicate delete. Read every message (UNVERIFIED wording of the individual messages; not on the API page) | The exception's messages; aws route53 list-resource-record-sets --hosted-zone-id <z> --start-record-name <n> --max-items 3 |
InvalidInput | 400 | Malformed input, for example an invalid name or value | The message names the field |
NoSuchHostedZone | 404 | Wrong hosted zone ID (it is Z…, without the /hostedzone/ prefix in the SDK: UNVERIFIED), or the zone is in another account | aws route53 list-hosted-zones-by-name --dns-name <domain> with the same credentials |
NoSuchHealthCheck | 404 | HealthCheckId doesn't exist | aws route53 get-health-check --health-check-id <id> |
PriorRequestNotComplete | 400 | The previous change to this zone is still being processed. Retry with increasing waits | aws route53 get-change --id <change-id> → Status (PENDING) |
| Throttling | 400 | Throttling / rate exceeded (UNVERIFIED code; common errors page not collected). Batch changes rather than sending many single-change calls | Calls per second in your code; SDK retry logs |
Hosted zones and delegation
- A public hosted zone has four name servers. The domain's registrar must list exactly those for the zone to answer for the domain.
- Several hosted zones can share a name. Only the one whose name servers the registrar lists is live.
- Deleting the live zone takes the domain offline until a new zone's name servers are set at the registrar and caches expire (up to 48 h).