Yeah, that's annoying. You spin up an EC2 instance, grab the public DNS name from the console, and it resolves to a 10.x.x.x address. You're not crazy—here's what's happening and how to fix it in about 10 minutes.
The Fast Fix: Alias Record in Route 53
The most common cause is that you're using a custom domain (like app.example.com) with a regular A record pointing to the instance's public IP. But the instance's public IP might have changed, or you never created an A record at all—and the only DNS name that works natively is the one AWS gives you (like ec2-203-0-113-5.compute-1.amazonaws.com).
If you're using Route 53, the cleanest fix is an alias record that points directly to the EC2 instance's public DNS name.
- Open the Route 53 console, go to Hosted zones, and pick your domain.
- Click Create record.
- For the name, enter the subdomain (e.g.,
app). - Toggle Alias to on.
- Under Route traffic to, choose Alias to EC2 instance and pick the region and instance.
- Click Create records.
That's it. Give it a few seconds for propagation, then test with dig app.example.com or nslookup.
Why This Works
Here's the key: when you use an alias record, Route 53 doesn't store a fixed IP. Instead, it dynamically resolves the instance's current public IP at query time. If your instance gets stopped and started, the public IP might change—but the alias record keeps pointing to the right address because it's tied to the instance ID, not the IP literal.
If you used a plain A record with the public IP, you'd hit this exact problem the moment the IP changes. The alias record sidesteps that entirely.
What If You're Not Using Route 53?
If you've got DNS hosted elsewhere (like Cloudflare or your registrar), you can't use an alias record. You'll need to use an Elastic IP so the public IP never changes, then update your A record to that static IP.
- In the EC2 console, go to Elastic IPs, allocate one, and associate it with your instance.
- Then update your external DNS A record to that Elastic IP.
This works because an Elastic IP stays with your account until you release it, even if you stop the instance.
Less Common Variations
1. VPC DNS Settings Are Off
If enableDnsHostnames or enableDnsSupport is disabled on your VPC, EC2 instances won't get a public DNS name at all. Instead, they'll only have a private DNS name. Check your VPC settings:
aws ec2 describe-vpc-attribute --vpc-id vpc-12345678 --attribute enableDnsSupport
aws ec2 describe-vpc-attribute --vpc-id vpc-12345678 --attribute enableDnsHostnames
Both should return true. If not, you can enable them:
aws ec2 modify-vpc-attribute --vpc-id vpc-12345678 --enable-dns-support "{\"Value\":true}"
aws ec2 modify-vpc-attribute --vpc-id vpc-12345678 --enable-dns-hostnames "{\"Value\":true}"
After that, stop and start the instance so it picks up the new DNS name.
2. Split-Horizon DNS Inside the VPC
Here's a subtle one: if you're testing from inside the same VPC (like from another EC2 instance), that's normal. AWS uses split-horizon DNS. The public DNS name resolves to a private IP when queried from inside the VPC, because traffic between instances stays on the private network. That's actually the intended behavior—it's faster and avoids NAT costs.
To verify from outside, SSH into the instance with its public IP and run dig from a machine outside the VPC, or use an online DNS checker.
3. Route 53 Record Still Points to Old IP
You might have an alias record that's fine, but a separate A record for the same name that's overriding it. Route 53 will use the most specific match, and if you have both an A record and an alias record for the same name, the A record wins. Delete the stale A record.
4. TTL Caching
If you just changed a record, your local DNS resolver (or your computer's cache) might still have the old value. Wait out the TTL—or flush your cache with sudo killall -HUP mDNSResponder on macOS or ipconfig /flushdns on Windows.
Prevention
The root cause is almost always a public IP that changed. Stop-and-start an instance, and unless you have an Elastic IP, the public IP is gone. So the prevention rules are simple:
- Always use Route 53 alias records for EC2 instances.
- If you can't, attach an Elastic IP and use that in your DNS.
- Enable both VPC DNS attributes from day one—new default VPCs have them on, but custom VPCs often don't.
- Never hard-code an instance's public IP in a config file. Use DNS names or the instance's metadata.
One more thing: if you're doing this a lot, consider using a load balancer or a dynamic DNS service, but for a single instance, the alias record is the right tool. It's rare that you need anything else.