This check flags a Route 53 registered domain whose registration has lapsed. An expired domain can take your site, email, and APIs offline and may be re-registered by an attacker. Renew it immediately and enable auto-renew to keep it from happening again.
Domains are the kind of infrastructure nobody thinks about until they break. They sit quietly for years, then one day the credit card on file expires, the renewal email lands in a shared inbox nobody reads, and your production domain quietly stops resolving. The route53_expired check exists to catch that situation before it turns into an outage or, worse, a hijack.
This post walks through what the check looks for, why an expired domain is more dangerous than it sounds, and exactly how to recover and prevent it.
What this check detects
The Domain Has Expired check inspects domains registered through Amazon Route 53 (the domain registrar, not just hosted zones) and reports any whose registration has passed its expiration date.
Route 53 plays two distinct roles that often get conflated:
- Domain registration: Route 53 acts as a registrar, holding your ownership of a domain like
example.comwith the relevant registry. - DNS hosting: Route 53 hosted zones answer DNS queries for a domain.
This check is concerned with the first role. When a registration lapses, the domain enters a series of registry-defined grace periods and eventually becomes available for anyone to register. The check reads the Expiry field returned by the Route 53 Domains API and compares it against the current date.
Note: Route 53 Domains is a global service whose API only lives in the us-east-1 region. If you script around it, point your client at us-east-1 regardless of where the rest of your infrastructure runs.
Why it matters
An expired domain is not a slow-burning hygiene issue. It is a live incident waiting for the grace period clock to run out. Here is what is actually at stake.
1. Total loss of resolution
Once a domain expires, registries typically suspend it. DNS stops resolving, which means everything tied to that name goes dark at once: your marketing site, customer dashboards, internal tools on subdomains, and any APIs your mobile apps or partners depend on. There is no graceful degradation. The name simply stops answering.
2. Email delivery collapses
If the domain handles email through MX records, inbound mail bounces and outbound mail fails SPF, DKIM, and DMARC checks because the records can no longer be queried. Password resets, billing notices, and customer support all break, and some of those failures are silent.
3. Domain hijacking and takeover
This is the worst case. After the various grace periods lapse, the domain is released and anyone can register it. An attacker who picks it up controls your DNS entirely. They can:
- Stand up a lookalike site to phish your users with your real domain in the address bar.
- Issue valid TLS certificates for your domain using DNS or HTTP validation, since they now control the records.
- Receive password reset emails and account verification messages, then pivot into accounts on third-party services that trust your domain.
- Hijack OAuth callbacks, webhooks, and any integration that resolves your hostname.
Danger: Domain expiration is one of the few misconfigurations where doing nothing can hand full control of your brand to an attacker. Recovery after the redemption period closes may be impossible if someone else registers the name first. Treat an expired production domain as a sev-1.
4. Reputation and trust damage
Even a brief outage on a primary domain erodes customer trust, and a phishing site running on your real domain can do lasting brand damage. The cost of a renewal is trivial. The cost of losing the domain is not.
Understanding the expiration timeline
Knowing where you are in the lifecycle determines how urgently you need to act.
- Expiration date: The registration lapses. The domain may still work briefly, but you are now on borrowed time.
- Auto-renew grace period: For most TLDs, Route 53 allows renewal at the standard price for roughly a few days to several weeks after expiry, depending on the TLD.
- Redemption period: The domain is suspended and resolution stops. You can usually still recover it, but a restoration fee applies, often $50 or more per TLD rules.
- Pending delete: A short window where the domain cannot be renewed by anyone.
- Released: The domain returns to the open market and anyone can register it.
Warning: Exact timings vary by TLD and registry, and some TLDs have no redemption period at all. Do not assume you have a comfortable buffer. The moment this check fires, act.
How to fix it
The fix is straightforward: confirm the domain's status and renew it. Move fast, because the cost and difficulty of recovery climb as the timeline advances.
Step 1: Confirm the current status
Check the domain's registration details to see the exact expiry date, current status codes, and whether auto-renew is on.
aws route53domains get-domain-detail \
--region us-east-1 \
--domain-name example.com
Look at the ExpirationDate, AutoRenew, and StatusList fields in the response. Status codes like clientHold or pendingDelete tell you where in the lifecycle the domain sits.
Step 2: Renew the domain
You can renew through the console or the CLI. Via the CLI, you need the current expiry year, which the previous command returned.
Warning: Renewing a domain charges your AWS account immediately for the registration period, and a domain in the redemption period incurs an additional restoration fee. Make sure a valid payment method is on file before you run this, or the operation will fail.
aws route53domains renew-domain \
--region us-east-1 \
--domain-name example.com \
--duration-in-years 1 \
--current-expiry-year 2024
The command returns an OperationId. Renewals are asynchronous, so track it:
aws route53domains get-operation-detail \
--region us-east-1 \
--operation-id
Step 3: Renew through the console (alternative)
- Open the Route 53 console and go to Registered domains.
- Select the expired domain from the list.
- Choose Renew and pick the renewal duration.
- Confirm the charge and submit.
If the domain has already entered the redemption period, the console surfaces a Restore option instead. Restoration carries an extra fee and can take longer to process.
Step 4: Verify resolution and certificates
After renewal propagates, confirm the domain resolves and that nothing was tampered with while it was vulnerable.
# Confirm the domain resolves and check the nameservers
dig example.com NS +short
dig example.com A +short
# Verify your TLS certificate is still the one you expect
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -issuer -subject -dates
If the domain was exposed during a window where an attacker could have requested a certificate, review your CT logs to be safe.
# Look for unexpected certificates issued for your domain
curl -s "https://crt.sh/?q=example.com&output=json" | jq '.[].name_value' | sort -u
How to prevent it from happening again
Renewing once solves today's problem. The goal is to make expiration impossible to reach by accident.
Enable auto-renew
This is the single most effective control. Route 53 will renew the domain automatically before it lapses, as long as a valid payment method is on file.
aws route53domains enable-domain-auto-renew \
--region us-east-1 \
--domain-name example.com
Confirm it stuck:
aws route53domains get-domain-detail \
--region us-east-1 \
--domain-name example.com \
--query 'AutoRenew'
Tip: Loop over every registered domain and enable auto-renew in one pass so a new domain never slips through:
aws route53domains list-domains --region us-east-1 --query 'Domains[].DomainName' --output text | tr '\t' '\n' | xargs -I{} aws route53domains enable-domain-auto-renew --region us-east-1 --domain-name {}
Keep billing and contacts valid
Auto-renew silently fails if the payment method is declined or expired. Two things to lock down:
- Keep a current credit card on the AWS account, and prefer a card with a long expiry or a corporate card managed by finance rather than an individual's personal card.
- Make sure the registrant and technical contact emails point to a monitored distribution list, not a single person who might leave the company. Registries send renewal and verification notices to these addresses.
Audit expiry dates on a schedule
Run a recurring job that reports any domain expiring within a threshold, well ahead of the lapse. A simple version checks every registered domain and flags ones inside a 45-day window:
#!/usr/bin/env bash
set -euo pipefail
THRESHOLD_DAYS=45
NOW=$(date +%s)
aws route53domains list-domains --region us-east-1 \
--query 'Domains[].DomainName' --output text | tr '\t' '\n' | while read -r domain; do
expiry=$(aws route53domains get-domain-detail --region us-east-1 \
--domain-name "$domain" --query 'ExpirationDate' --output text)
expiry_epoch=$(date -d "$expiry" +%s)
days_left=$(( (expiry_epoch - NOW) / 86400 ))
if [ "$days_left" -lt "$THRESHOLD_DAYS" ]; then
echo "WARNING: $domain expires in $days_left days ($expiry)"
fi
done
Wire the output into Slack, PagerDuty, or an email alert so it lands somewhere a human will see it.
Enforce auto-renew as policy
If you manage domains as code or want a hard gate, treat auto-renew as a required state. With Terraform, the aws_route53domains_registered_domain resource lets you assert it:
resource "aws_route53domains_registered_domain" "example" {
domain_name = "example.com"
auto_renew = true
# Drift here means someone disabled auto-renew out of band
}
Run terraform plan in CI on a schedule. Any drift on auto_renew shows up as a proposed change and fails the gate, surfacing the problem before the domain is ever at risk.
Tip: Pair the Terraform drift check with the Lensix route53_expired check. Terraform catches a disabled auto-renew flag, and Lensix catches the downstream condition of an actually expired domain. Two layers, no single point of failure.
Best practices
- Turn on auto-renew for every domain by default. The renewal cost is negligible compared to losing the name. There is rarely a good reason to leave it off for a domain you actually use.
- Enable transfer lock. Route 53's
TransferLockstatus blocks unauthorized transfers and adds a layer of protection against hijacking attempts. - Use role accounts for registrant contacts. Never tie a domain's renewal and recovery emails to one individual. Use a monitored alias owned by a team.
- Centralize domain ownership. Scattered domains across personal accounts and shadow IT are how registrations get forgotten. Consolidate into accounts your team actively monitors.
- Register for longer terms on critical domains. A multi-year registration reduces the number of renewal events and the chances of a single missed payment causing a lapse.
- Alert early and at multiple thresholds. One reminder at 45 days, another at 14, and a final at 3 gives you margin even if the first alert is missed.
- Treat domains as production infrastructure. They belong in your inventory, your monitoring, and your incident runbooks, not in a forgotten corner of a billing account.
An expired domain is one of the rare misconfigurations that is both cheap to prevent and catastrophic to ignore. Enable auto-renew, keep billing and contacts current, monitor expiry dates, and let the route53_expired check be the backstop that catches anything that slips through.

