---
cuppy_hub: aws
cuppy_path: reference/route53/records-and-changes.md
cuppy_section: docs
cuppy_doc: 5HK2-FMTD
cuppy_doc_uuid: aecb9881-ce1a-4c15-9f44-b35f0a536425
cuppy_permalink: https://cuppy.io/aws/d/5HK2-FMTD
cuppy_version: 4
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/aws/docs/reference/route53/records-and-changes
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 75523c720c4e6ca126f5a1e1cb5df64c2f57939ba1e4d9a2eaa29172b18ee96f
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Route 53 records, alias targets and change batches

**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[]` with `Action` set to `CREATE` (fails if the record exists), `UPSERT` (create or update) or `DELETE` (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 }`. Here `HostedZoneId` is the **target resource's** zone ID, not yours.
- Routing-policy fields: `SetIdentifier`, plus one of `Weight` (0–255), `Region` (latency), `Failover` (`PRIMARY`/`SECONDARY`), `GeoLocation`, `GeoProximityLocation`, `CidrRoutingConfig` or `MultiValueAnswer`, and optionally `HealthCheckId`.
- 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).


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 131 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/aws/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
