EC2 Cannot Resolve DNS Names? Fix "Temporary Failure in Name Resolution", "Could Not Resolve Host" and VPC DNS: enableDnsSupport, DHCP Options, 169.254.169.253
When an EC2 instance can't resolve DNS names ("Temporary failure in name resolution", "Could not resolve host", "Name or service not known", or "No such host is known" on Windows), the cause is one of six things. First, the VPC's enableDnsSupport attribute is off. Second, the VPC's DHCP options set points instances at custom DNS servers that are unreachable or don't forward AWS names. Third, the operating system's DNS settings were changed (a hand-edited /etc/resolv.conf, a stopped systemd-resolved, a static DNS server on Windows). Fourth, a private hosted zone isn't associated with the VPC, or enableDnsHostnames is off. Fifth, a Route 53 Resolver DNS Firewall rule blocks the domain. Sixth, the instance is hitting the 1,024 packets-per-second limit on link-local traffic, which causes intermittent failures. The Amazon DNS server lives at 169.254.169.253 (and at your VPC's base address plus two, such as 10.0.0.2), needs no internet access, and isn't filtered by security groups or network ACLs. So test it directly with dig @169.254.169.253 amazon.com or Resolve-DnsName amazon.com -Server 169.254.169.253: if that works, the problem is your instance's configuration. Below: how to tell DNS failures from connectivity failures, every cause with its fix for Linux and Windows, containers, hybrid DNS, and a checklist.
Ethan's client ran its order system on a handful of EC2 instances in private subnets. One Tuesday morning every payment failed with the same line in the logs: curl: (6) Could not resolve host: api.payments.example. Nothing had been deployed. The network team, it turned out, had "tidied up" the VPC the evening before, replacing the default DHCP options set with one that pointed at the company's on-premises DNS servers, across a VPN that had gone down at midnight. Jake, who was in the office to pick up a refurbished laptop, asked the obvious question: "How can a computer forget how to find the internet?"
New to DNS on AWS? The cards below cover Route 53 and its Resolver, hosted zones, private subnets, peering DNS and VPC endpoints.
How DNS works for an EC2 instance
DNS is the internet's phone book: it turns a name such as api.payments.example into an IP address your instance can connect to. Every time your code, your package manager or your browser uses a name, the operating system asks a DNS resolver for the address first. If that question gets no answer, nothing else happens: the connection never starts, and you see a name resolution error instead of a timeout.
In a VPC, the resolver is normally the Amazon DNS server, also called the Route 53 Resolver or AmazonProvidedDNS. It is built into every Availability Zone, and your instance can reach it at three addresses:
- 169.254.169.253, a link-local IPv4 address that works from any instance in any VPC;
- fd00:ec2::253, its IPv6 equivalent (on instances built on the Nitro system);
- your VPC's primary IPv4 CIDR base plus two, such as
10.0.0.2for a VPC of10.0.0.0/16.
Four facts about it explain most of what goes wrong:
- It needs no internet access. Queries travel privately inside AWS's network. An instance in a private subnet with no NAT gateway can still resolve public names like
amazon.com; it just cannot connect to them. - Security groups and network ACLs do not filter it. You cannot block, or accidentally break, traffic to the Amazon DNS server with security group or network ACL rules. Custom DNS servers are a different story.
- It resolves AWS's own names: instance hostnames such as
ip-10-0-1-25.ec2.internal, private DNS for VPC endpoints, and records in Route 53 private hosted zones associated with the VPC. A DNS server outside the VPC cannot do that unless it forwards to the Amazon DNS server. - It has a rate limit. Each network interface can send at most 1,024 packets per second to link-local services, a total that also includes instance metadata and time service traffic. It cannot be raised.
Your instance learns which DNS server to use from the VPC's DHCP options set. The default option set says domain-name-servers = AmazonProvidedDNS, and the operating system writes that address into its configuration: /etc/resolv.conf (directly, or through systemd-resolved) on Linux, and the network adapter's DNS server list on Windows. If someone changes the DHCP options set, or the operating system's settings, the instance asks a different server.
Jake: "So the instance doesn't forget the internet. It forgets who to ask."
Ethan: "Exactly. Someone told all of them to ask a server that's switched off."
The 2-minute test: which part is broken?
Run these on the affected instance (through Session Manager or SSH if you can still reach it). They narrow the problem to one place.
On Linux
# 1. Which DNS server is the instance using?
cat /etc/resolv.conf
resolvectl status 2>/dev/null | grep -A2 "DNS Servers"
# 2. Does the normal path work?
dig amazon.com +short # or: nslookup amazon.com
# 3. Does the Amazon DNS server answer directly?
dig @169.254.169.253 amazon.com +short
# 4. Can it resolve AWS's own names?
dig @169.254.169.253 ec2.us-east-1.amazonaws.com +short
On Windows (PowerShell)
# 1. Which DNS servers is each adapter using?
Get-DnsClientServerAddress -AddressFamily IPv4
# 2. Does the normal path work?
Resolve-DnsName amazon.com
# 3. Does the Amazon DNS server answer directly?
Resolve-DnsName amazon.com -Server 169.254.169.253
# 4. Can it resolve AWS's own names?
Resolve-DnsName ec2.us-east-1.amazonaws.com -Server 169.254.169.253
Reading the results
| What you see | What it means | Go to |
|---|---|---|
| Step 1 shows a server other than the Amazon DNS server (an on-premises IP, 8.8.8.8, a domain controller) | The DHCP options set or the OS points elsewhere | DHCP options, Linux, Windows |
| Step 2 fails, step 3 works | The Amazon DNS server is fine; your configured server is not | DHCP options or OS settings |
| Step 3 fails too ("connection timed out; no servers could be reached") | enableDnsSupport is off, or the instance is throttled | VPC attributes, throttling |
| Step 3 returns NXDOMAIN or an unexpected address for one domain only | A DNS Firewall rule, or a private hosted zone overriding the public name | DNS Firewall, private zones |
| Public names work, your private names (db.internal.example) fail | Private hosted zone not associated with this VPC, or enableDnsHostnames off | Private zones |
| Everything resolves, but connections still fail | Not a DNS problem: no route to the internet or the target | DNS or no route? |
| Works most of the time, fails in bursts | Link-local packet limit, or a custom DNS server under load | Intermittent failures |
On Ethan's client's instances, /etc/resolv.conf listed nameserver 192.168.10.5 (the on-premises server), dig amazon.com timed out, and dig @169.254.169.253 amazon.com answered instantly. Diagnosis in under a minute: the DHCP options set.
First, make sure it really is DNS
Many "DNS problems" are not DNS problems. The error text tells you which kind you have:
- DNS failure: "Temporary failure in name resolution", "Could not resolve host", "Name or service not known", "getaddrinfo ENOTFOUND" (Node.js), "UnknownHostException" (Java), "No such host is known" or "The remote name could not be resolved" (Windows and .NET), "Could not connect to the endpoint URL" when the hostname cannot be resolved (AWS CLI). The program never got an IP address.
- Connectivity failure: "Connection timed out", "Network is unreachable", "Connection refused", "Failed to connect to host port 443". The name resolved to an address, but the instance cannot reach it.
DNS error messages by tool and language
| Where you see it | DNS failure message | Not DNS (connectivity) |
|---|---|---|
| curl | curl: (6) Could not resolve host | curl: (7) Failed to connect; (28) Connection timed out |
| ping, ssh, apt, dnf, yum | Temporary failure in name resolution; Name or service not known; Could not resolve host | Network is unreachable; Connection timed out |
| sudo | sudo: unable to resolve host ip-10-0-1-25: Name or service not known | (not applicable) |
| Python (requests, boto3) | socket.gaierror: [Errno -3] Temporary failure in name resolution; NameResolutionError | ConnectTimeoutError; EndpointConnectionError after the name resolved |
| Node.js | getaddrinfo ENOTFOUND; getaddrinfo EAI_AGAIN | ETIMEDOUT; ECONNREFUSED |
| Java | java.net.UnknownHostException | java.net.ConnectException; SocketTimeoutException |
| Windows, PowerShell, .NET | No such host is known; The remote name could not be resolved; DNS name does not exist | A connection attempt failed because the connected party did not properly respond |
| AWS CLI | Could not connect to the endpoint URL (when the host name cannot be resolved) | Connect timeout on endpoint URL |
EAI_AGAIN in Node.js and "Temporary failure" on Linux both mean the resolver did not answer in time, which points at an unreachable or overloaded DNS server or at throttling, while ENOTFOUND and NXDOMAIN mean a server answered that the name does not exist, which points at a wrong name, a missing private zone record or a DNS Firewall block.
The second kind usually means the instance has no path out: a private subnet with no NAT gateway, a route table without a 0.0.0.0/0 route, a security group without outbound rules, or a network ACL blocking return traffic. Because the Amazon DNS server works without internet access, a private instance with no NAT gateway shows exactly this pattern: names resolve, connections hang. Our private subnet no internet guide fixes that case. For AWS service endpoints, a VPC endpoint can replace the NAT gateway; see our VPC endpoint guide.
Cause 1: the VPC's DNS attributes are off
Every VPC has two DNS attributes:
- enableDnsSupport (default
true): whether the Amazon DNS server answers queries for this VPC. If it isfalse, every query to 169.254.169.253 and to the VPC+2 address fails, and every instance using AmazonProvidedDNS loses name resolution completely. - enableDnsHostnames (default
false, except in the default VPC): whether instances with public IP addresses get public DNS hostnames, and, together with enableDnsSupport, whether the Amazon DNS server resolves Amazon-provided private hostnames.
Both must be true if you use private hosted zones or private DNS for interface VPC endpoints (PrivateLink), which is most production VPCs. Check and fix them:
aws ec2 describe-vpc-attribute --vpc-id vpc-0a1b2c3d4e5f67890 --attribute enableDnsSupport
aws ec2 describe-vpc-attribute --vpc-id vpc-0a1b2c3d4e5f67890 --attribute enableDnsHostnames
aws ec2 modify-vpc-attribute --vpc-id vpc-0a1b2c3d4e5f67890 --enable-dns-support "{\"Value\":true}"
aws ec2 modify-vpc-attribute --vpc-id vpc-0a1b2c3d4e5f67890 --enable-dns-hostnames "{\"Value\":true}"
Each command changes one attribute; you cannot change both in one call. In the console: VPC > Your VPCs, select the VPC, Actions > Edit VPC settings, and tick Enable DNS resolution and Enable DNS hostnames. The change takes effect within moments; no reboot is needed.
In Terraform, set both on the VPC, and keep the DHCP options explicit so nobody changes them by hand:
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
}
resource "aws_vpc_dhcp_options" "amazon_dns" {
domain_name = "ec2.internal"
domain_name_servers = ["AmazonProvidedDNS"]
}
resource "aws_vpc_dhcp_options_association" "main" {
vpc_id = aws_vpc.main.id
dhcp_options_id = aws_vpc_dhcp_options.amazon_dns.id
}
In CloudFormation, the matching properties are EnableDnsSupport and EnableDnsHostnames on AWS::EC2::VPC. VPCs created by older Terraform modules, CloudFormation templates or scripts sometimes have enable_dns_hostnames = false, which is the API default for new VPCs. If a private hosted zone or a VPC endpoint's private DNS name "does not work in one VPC only," check this attribute first.
Cause 2: the DHCP options set points at the wrong DNS servers
A DHCP options set tells instances which DNS servers, domain name, NTP servers and NetBIOS settings to use. Each VPC has exactly one associated. Companies change it for good reasons, usually to point instances at Active Directory domain controllers or on-premises DNS servers, and that is where most outages come from:
- The custom DNS servers are on-premises, across a VPN or Direct Connect, and the link goes down. Every lookup fails, even for
amazon.com. - The custom servers are reachable but do not forward AWS names to the Amazon DNS server, so instance hostnames, private hosted zones and VPC endpoint names fail while public names work.
- The custom servers are EC2 instances or domain controllers whose security groups do not allow UDP and TCP port 53 from the VPC. Unlike the Amazon DNS server, custom DNS servers are subject to security groups and network ACLs.
- Someone typed a wrong IP address, or the servers were replaced and the option set was never updated.
Check which option set the VPC uses
aws ec2 describe-vpcs --vpc-ids vpc-0a1b2c3d4e5f67890 --query "Vpcs[].DhcpOptionsId" --output text
aws ec2 describe-dhcp-options --dhcp-options-ids dopt-0123456789abcdef0
If domain-name-servers shows anything other than AmazonProvidedDNS, that is the server list your instances use.
Fix it
- Fastest recovery: associate an option set that uses AmazonProvidedDNS (you can create one with
domain-name-servers = AmazonProvidedDNS, or re-associate the original). This is what Ethan did at 9:40 that Tuesday; payments recovered within minutes. - Better long-term design for hybrid networks: keep AmazonProvidedDNS in the option set, and use Route 53 Resolver outbound endpoints and forwarding rules to send only the company's internal domains (such as
corp.example.com) to the on-premises servers. If the VPN fails, internal names fail, but the internet and AWS names keep working. See hybrid DNS. - If you must use custom DNS servers (for example Active Directory), make sure they are highly available inside AWS (two domain controllers in different Availability Zones), allow port 53 from the VPC, and forward everything they do not own to the Amazon DNS server.
aws ec2 create-dhcp-options --dhcp-configurations "Key=domain-name-servers,Values=AmazonProvidedDNS" "Key=domain-name,Values=ec2.internal"
aws ec2 associate-dhcp-options --dhcp-options-id dopt-0fedcba9876543210 --vpc-id vpc-0a1b2c3d4e5f67890
Use ec2.internal as the domain name in US East (N. Virginia) and REGION.compute.internal in other Regions, such as eu-west-1.compute.internal.
The same fix in the console, step by step
- Open the VPC console and choose DHCP option sets.
- Choose Create DHCP option set. Give it a name tag such as
amazon-dns. - For Domain name, enter
ec2.internal(US East, N. Virginia) orREGION.compute.internal. - For Domain name servers, choose AmazonProvidedDNS. Leave the other fields empty unless you need custom NTP or NetBIOS settings.
- Choose Create DHCP option set.
- Choose Your VPCs, select the VPC, then Actions > Edit VPC settings.
- Under DHCP option set, choose the new set and save.
- Renew DHCP leases or reboot the affected instances, then test again with the 2-minute test.
Keep the old option set until you are sure nothing else needs it; a VPC can have only one option set at a time, and switching back is the same two clicks.
Instances pick up the change on lease renewal
Changing the VPC's option set does not instantly change running instances; each instance applies it when its DHCP lease renews, which can take a while. To apply it now: reboot the instance, or renew the lease. On Amazon Linux 2023 and Ubuntu, sudo networkctl renew eth0 (or ens5, whatever ip link shows) renews through systemd-networkd; on Amazon Linux 2, sudo dhclient -r && sudo dhclient; on Windows, ipconfig /renew. Then check resolv.conf or Get-DnsClientServerAddress again.
Jake: "So one setting in the VPC broke every server at once?"
Ethan: "One setting, and one VPN link it depended on. That's why I don't let the internet depend on the VPN anymore."
Cause 3a: the Linux instance's own DNS settings
If the VPC is fine and dig @169.254.169.253 works but normal lookups fail, the operating system is asking the wrong place, or nothing at all.
Amazon Linux 2023 and Ubuntu: systemd-resolved
Recent Amazon Linux and Ubuntu releases use systemd-resolved. /etc/resolv.conf is a link to a stub file that says nameserver 127.0.0.53, a local cache that forwards to the real servers learned from DHCP. Common breakages:
- systemd-resolved is stopped or disabled. Every lookup to 127.0.0.53 fails. Check with
systemctl status systemd-resolvedand start it withsudo systemctl enable --now systemd-resolved. - /etc/resolv.conf was replaced with a plain file (by a script, a configuration tool or a VPN client) pointing at a server that does not answer. Restore the link:
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf. - A static DNS server was configured in a netplan or systemd-networkd file.
resolvectl statusshows the servers per interface; remove the static entry and runsudo netplan apply(Ubuntu) orsudo networkctl reload.
resolvectl query amazon.com tests the full systemd path, and resolvectl flush-caches clears cached failures after you fix the cause.
Amazon Linux 2 and older distributions: dhclient
Amazon Linux 2 writes /etc/resolv.conf from DHCP through dhclient, with nameserver 10.0.0.2 (your VPC+2) and a search domain. If someone edited the file by hand, the next lease renewal may overwrite it, or a custom /etc/dhcp/dhclient.conf with supersede domain-name-servers may keep forcing the wrong server. Remove the override and renew the lease.
Other Linux causes
- /etc/nsswitch.conf without
dnson thehosts:line: names are looked up only in/etc/hosts. - A stale entry in /etc/hosts pointing a name at an old address: everything "resolves," to the wrong place.
- A host firewall (iptables, nftables, firewalld) dropping outbound UDP 53 or traffic to 169.254.0.0/16.
- A VPN or proxy agent installed on the instance that rewrites DNS settings.
"sudo: unable to resolve host": the instance cannot resolve its own name
One of the most searched EC2 DNS messages is not about the internet at all: "sudo: unable to resolve host ip-10-0-1-25: Name or service not known". sudo looks up the instance's own hostname, and the lookup fails. The command still runs after a short delay, but the message appears every time. The causes:
- You changed the hostname (with
hostnamectl set-hostname shop-api, for example) and/etc/hostshas no entry for the new name. Add one: a line such as127.0.1.1 shop-apion Ubuntu, or the private IP followed by the name on Amazon Linux. Thepreserve_hostname: truesetting in cloud-init keeps your hostname across reboots. - The VPC has enableDnsHostnames or enableDnsSupport off, so the Amazon DNS server will not resolve Amazon-provided private hostnames such as
ip-10-0-1-25.ec2.internal. - Custom DNS servers in the DHCP options set do not know AWS's instance names and do not forward the
compute.internalorec2.internaldomains to the Amazon DNS server. - The instance uses resource-based names (hostnames such as
i-0123456789abcdef0.ec2.internal) while scripts or/etc/hostsstill expect IP-based names, or the other way round.
Check with hostname -f and getent hosts $(hostname): both should return the name and its private IP. Services built on Hadoop, such as Amazon EMR, require instances to resolve their own fully qualified names, so with custom DNS servers, add a conditional forwarder for REGION.compute.internal to the Amazon DNS server.
Testing tools: dig, nslookup, host and getent
- dig gives the most detail (response code, which server answered, TTL). On Amazon Linux 2023 install it with
sudo dnf install -y bind-utils; on Ubuntu,sudo apt install -y dnsutils. - nslookup is on almost every system, including Windows, and is fine for quick checks.
- getent hosts NAME uses the same path as applications on Linux (hosts file, nsswitch.conf, the system resolver), so it reproduces what your program sees, while dig and nslookup query a DNS server directly and skip the hosts file.
- Resolve-DnsName is the PowerShell tool on Windows; add
-DnsOnlyto skip the hosts file and cache, or-Serverto pick a server.
A useful pair on Linux: if dig amazon.com works but getent hosts amazon.com fails, the problem is in nsswitch.conf, the hosts file or the local resolver service, not the DNS server.
Cause 3b: the Windows instance's own DNS settings
On Windows Server, the adapter's DNS server list normally comes from DHCP and shows the VPC+2 address. Check it with Get-DnsClientServerAddress or ipconfig /all.
- A static DNS server was set on the network adapter (often left over from an AMI built elsewhere, or set when joining a domain). Switch the adapter back to DHCP-provided DNS:
Get-NetAdapter
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ResetServerAddresses
ipconfig /renew
ipconfig /flushdns
Resolve-DnsName amazon.com
- Domain-joined instances should use the domain controllers as DNS servers, and the domain controllers should have conditional or general forwarders to the Amazon DNS server (the VPC+2 address of their own VPC) for everything they are not authoritative for. When the domain controllers are down or unreachable, every domain member loses DNS, which is why at least two, in different Availability Zones, is the norm. With AWS Managed Microsoft AD, the domain controllers are run for you in two Availability Zones; check their DNS forwarders if AWS names fail from domain members.
- Negative caching: Windows caches failed lookups for a short time. After a fix,
ipconfig /flushdns(orClear-DnsClientCache) makes the instance ask again right away. - The hosts file at
C:\Windows\System32\drivers\etc\hostscan override names, exactly like/etc/hostson Linux.
Short names fail, full names work: DNS search suffixes
If db01.internal.example.com resolves but plain db01 does not, the problem is the search suffix list, not the DNS server. The resolver appends each suffix in the list to a short name and tries them in turn. On Linux, the list is the search line in /etc/resolv.conf (from the DHCP options set's domain-name, or from systemd-resolved's Domains setting). On Windows, set it for the whole instance:
Set-DnsClientGlobalSetting -SuffixSearchList @("internal.example.com", "ec2.internal")
Get-DnsClientGlobalSetting
A DHCP options set holds only one domain name, so for several internal domains, set the search list on the instances (through Group Policy, a user data script or configuration management), or use full names in configuration files, which is more reliable anyway.
Cause 4: private hosted zone names do not resolve
If public names work but your own internal names (db.internal.example.com, api.service.local) do not, the problem is usually the private hosted zone, not the instance:
- The zone is not associated with this VPC. A private hosted zone answers only inside the VPCs associated with it. A new VPC, or a VPC in another account, needs its own association (cross-account associations need an authorization from the zone owner first). Check with
aws route53 get-hosted-zone --id Z0123456789ABCDEFGHIJand look atVPCs. - enableDnsHostnames or enableDnsSupport is off in the VPC (see cause 1).
- The instance uses custom DNS servers that do not forward the zone's domain to the Amazon DNS server.
- Overlapping names: a private zone for
example.comassociated with the VPC answers everyexample.comquery from that VPC, including public names you did not add to the private zone, which then return NXDOMAIN. Add the missing records to the private zone, or use a more specific private zone such asinternal.example.com. - Peered or connected VPCs do not inherit the zone; associate the zone with them too, or use Route 53 Resolver endpoints. Our VPC peering DNS guide covers the peering-specific settings.
Interface VPC endpoints with private DNS enabled work the same way: they create a hidden private zone for the service's public name (such as secretsmanager.us-east-1.amazonaws.com) in your VPC, and they need both DNS attributes on. If an SDK call from a private subnet still goes to the public address, check those attributes and the endpoint's private DNS setting.
Cause 5: Route 53 Resolver DNS Firewall is blocking the domain
Route 53 Resolver DNS Firewall lets security teams block or allow domains for queries that go through the Amazon DNS server in a VPC, typically to stop malware from reaching command-and-control domains. A blocked domain looks like a DNS failure on the instance: depending on the rule, the answer is NXDOMAIN ("non-existent domain"), NODATA, or an override to another address.
- In the VPC console, open DNS Firewall > Rule groups and check which rule groups are associated with the instance's VPC.
- Look at the rules' domain lists for the name that fails (including wildcard entries such as
*.example), and at the AWS managed domain lists, which occasionally include domains you need. - Turn on Resolver query logging for the VPC, which records every query, its response code and, when DNS Firewall acts, the rule that matched.
If your company also runs AWS Network Firewall with domain filtering, a blocked domain there behaves differently: the name resolves, but the HTTPS connection fails. Our Network Firewall guide covers that layer.
Cause 6: intermittent failures and DNS throttling
If lookups fail only sometimes, in bursts, especially on busy instances, check the link-local packet limit: each network interface can send at most 1,024 packets per second to link-local services combined, which includes Amazon DNS queries, instance metadata (IMDS) requests, Amazon Time Sync requests and, on Windows, the licensing service. Above that, packets are dropped, and lookups fail or time out. The limit cannot be raised.
Signs you are hitting it: an application that resolves the same names thousands of times a second (no DNS caching), a container host running hundreds of containers that all resolve through the host's network interface, or code that calls the metadata service for credentials on every request. The ENA network driver exposes a counter for this, linklocal_allowance_exceeded, which you can read with ethtool -S eth0 | grep linklocal on Linux; a value that keeps rising confirms throttling.
Fixes, in order of impact:
- Cache DNS on the instance. systemd-resolved already caches on recent distributions; on others, run a local cache such as
dnsmasqorunbound, ornscd. - Cache in the application. Check your runtime's DNS caching: Java's behavior is controlled by
networkaddress.cache.ttl, and Node.js does not cachedns.lookupresults itself, so a busy Node service relies entirely on the operating system's cache. Reuse connections and clients rather than resolving per request. - Cache metadata credentials instead of fetching them from IMDS on every call; the AWS SDKs already do this when you reuse a client.
- Spread the load across more network interfaces or instances if one instance truly needs a high query rate.
Intermittent failures with custom DNS servers are more often the servers themselves: overloaded domain controllers, a single DNS server for a whole VPC, or on-premises servers across a congested link.
Docker and containers on EC2: DNS that works on the host but not inside
A classic EC2 surprise: dig amazon.com works on the host, but inside a Docker container the same lookup fails. Docker builds each container's DNS configuration from the host's, but a loopback address such as 127.0.0.1 means nothing inside the container's own network namespace, so Docker cannot pass it through. On hosts that use systemd-resolved, Docker reads the real upstream servers from systemd's own file, which normally works. On hosts that point /etc/resolv.conf only at a local cache such as dnsmasq or unbound on 127.0.0.1, Docker falls back to public resolvers (8.8.8.8 and 8.8.4.4). On an instance in a private subnet without a NAT gateway, or in a VPC whose egress filtering blocks outside DNS, those fallbacks are unreachable, and every lookup in the container fails. A custom DNS setting in a Compose file or a container image can cause the same symptom.
The reliable fix is to give Docker the Amazon DNS server explicitly, in /etc/docker/daemon.json:
{
"dns": ["169.254.169.253"]
}
Then sudo systemctl restart docker and recreate the containers. For a single container, docker run --dns 169.254.169.253 ... does the same. Containers on ECS with the awsvpc network mode (and Fargate) get their own network interface and use the VPC's DNS directly; Kubernetes on EKS uses CoreDNS, which forwards to the VPC resolver, so DNS failures there usually mean CoreDNS itself is unhealthy, covered in our CoreDNS guide.
Hybrid DNS done right: Route 53 Resolver endpoints
The root cause of Ethan's Tuesday outage was a design that sent all DNS, including the internet's, through on-premises servers over a VPN. The pattern that holds up in hybrid networks keeps the Amazon DNS server as every instance's resolver and adds targeted forwarding:
- Outbound endpoint plus forwarding rules: a Route 53 Resolver outbound endpoint (network interfaces in two or more subnets) sends queries for chosen domains, such as
corp.example.com, to your on-premises DNS servers. Everything else is resolved by AWS as usual. Share the rules with other accounts through AWS RAM and associate them with every VPC that needs them. - Inbound endpoint: on-premises DNS servers forward queries for your AWS domains (private hosted zones, instance names) to a Route 53 Resolver inbound endpoint in the VPC, so offices can resolve AWS names too.
- Endpoint security groups must allow UDP and TCP 53: outbound endpoints toward the on-premises servers, inbound endpoints from the on-premises network.
With this design, a VPN failure breaks only corp.example.com lookups from AWS, and the payment provider's API keeps resolving. Resolver endpoints are billed per network interface per hour plus per million queries, so check the Route 53 pricing page for your Region when you size them. Our Route 53 vs Route 53 Resolver guide explains the pieces, and the Client VPN DNS guide covers the remote-user side.
Jake: "So now if the VPN breaks, only the office stuff breaks?"
Ethan: "Only the office stuff, and the shop keeps taking payments. That's the whole point."
AWS service endpoints from private subnets
Private instances often fail on AWS API calls, and the error looks like DNS: the AWS CLI's "Could not connect to the endpoint URL: https://sts.us-east-1.amazonaws.com/". The name usually resolves fine; what fails is the connection, because a private subnet with no NAT gateway cannot reach the public service address. There are two fixes, and DNS is part of both:
- Add a NAT gateway route for internet access. The service names resolve to public addresses, and traffic goes out through the NAT gateway.
- Add interface VPC endpoints (or a gateway endpoint for S3 and DynamoDB). With private DNS enabled on an interface endpoint, the service's normal name (such as
sts.us-east-1.amazonaws.com) resolves to the endpoint's private IP addresses inside your VPC, so code needs no changes. That only works when the VPC has both DNS attributes on and instances use the Amazon DNS server (or custom servers that forward to it).
To check which one you are getting, run dig sts.us-east-1.amazonaws.com +short on the instance. Private addresses from your VPC's range mean the endpoint's private DNS is working; public addresses mean the endpoint is missing, its private DNS is off, or the instance is not using the Amazon DNS server. Gateway endpoints for S3 work differently (routes, not DNS), as our S3 VPC endpoint guide explains.
IPv6-only subnets and DNS64
Instances in IPv6-only subnets reach the Amazon DNS server at fd00:ec2::253 (on Nitro-based instances), and the IPv4 link-local address 169.254.169.253 still works when AmazonProvidedDNS is the DHCP name server. To reach IPv4-only destinations from an IPv6-only instance, turn on DNS64 on the subnet, so the resolver synthesizes IPv6 addresses for IPv4-only names, and route the 64:ff9b::/96 prefix to a NAT gateway, which performs the translation (NAT64). Without DNS64, IPv4-only names return no IPv6 address and look like resolution failures to IPv6-only applications.
Dual-stack instances can also hit a subtler problem: a name returns both an IPv6 (AAAA) and an IPv4 (A) address, the application tries IPv6 first, and the subnet has no IPv6 route to the internet. The lookup succeeded, but connections hang until they fall back to IPv4. Add an IPv6 route (an internet gateway or egress-only internet gateway) or configure the application to prefer IPv4.
Monitoring DNS so you hear about failures first
In Ethan's story, customers found the outage before the company did. Two cheap measures change that.
Route 53 Resolver query logging with an alarm
Query logging records every DNS query that instances in a VPC send through the Amazon DNS server: the name, the query type, the response code (rcode), the answers, and the source instance. Create a query logging configuration in the Route 53 console (Resolver > Query logging), choose a CloudWatch Logs log group as the destination, and associate it with the VPC. Then this CloudWatch Logs Insights query shows what is failing:
fields @timestamp, query_name, rcode, srcids.instance
| filter rcode != "NOERROR"
| stats count(*) as failures by rcode, query_name
| sort failures desc
| limit 20
A metric filter on the log group that counts SERVFAIL responses, with a CloudWatch alarm on a sudden rise, catches broken forwarders and unreachable on-premises servers within minutes. Query logs are billed as CloudWatch Logs ingestion and storage, so on very busy VPCs, log to S3 instead or set a short retention.
Note that query logging sees only queries that go through the Amazon DNS server. If the DHCP options set sends instances straight to custom DNS servers, those queries never appear, which is one more reason to keep AmazonProvidedDNS in place and forward selectively.
A synthetic check from inside the VPC
A tiny scheduled job (a Lambda function in the VPC, or a cron entry on an instance) that resolves the three or four names your business depends on, such as your payment provider, your database endpoint and an AWS service endpoint, and publishes a CloudWatch metric or fails loudly when one does not resolve. It costs almost nothing and tests the path your applications actually use.
The EC2 DNS troubleshooting checklist
- Confirm it is DNS: the error mentions resolving a name, not a timeout or refusal.
- Check which server the instance uses:
cat /etc/resolv.conf,resolvectl status, orGet-DnsClientServerAddress. - Query the Amazon DNS server directly:
dig @169.254.169.253 amazon.comorResolve-DnsName amazon.com -Server 169.254.169.253. - If that fails: check enableDnsSupport, DNS Firewall rules, and the
linklocal_allowance_exceededcounter. - If that works but normal lookups fail: check the VPC's DHCP options set, then the OS settings (systemd-resolved, resolv.conf, static DNS on Windows, hosts files).
- If only private names fail: check the private hosted zone's VPC associations and enableDnsHostnames, and forwarding on custom DNS servers.
- If only containers fail: set Docker's DNS to 169.254.169.253.
- After a fix: renew DHCP leases or reboot, and flush DNS caches (
resolvectl flush-caches,ipconfig /flushdns). - Prevent the next one: keep AmazonProvidedDNS in DHCP options, forward only internal domains with Resolver endpoints, run DNS servers in pairs, and turn on Resolver query logging.
Frequently asked questions
Why can't my EC2 instance resolve DNS names?
Usually the VPC's DHCP options set points at custom DNS servers that are unreachable or not forwarding, the operating system's DNS settings were changed, or the VPC's enableDnsSupport attribute is off. DNS Firewall rules and the link-local packet limit cause rarer cases.
What is the DNS server IP address in an AWS VPC?
The Amazon DNS server is at 169.254.169.253, at fd00:ec2::253 for IPv6 on Nitro instances, and at the VPC's primary IPv4 CIDR base plus two, such as 10.0.0.2 for 10.0.0.0/16.
How do I fix "Temporary failure in name resolution" on EC2?
Test with dig @169.254.169.253 amazon.com. If that works, restore the instance's DNS settings (systemd-resolved, resolv.conf) or the VPC's DHCP options set to AmazonProvidedDNS. If it fails, turn on enableDnsSupport and check DNS Firewall rules.
Do security groups block DNS on EC2?
Not for the Amazon DNS server: traffic to it cannot be filtered by security groups or network ACLs. Custom DNS servers, such as domain controllers, do need UDP and TCP port 53 allowed.
Does an EC2 instance need internet access for DNS?
No. The Amazon DNS server is reached privately inside AWS, so instances in private subnets without a NAT gateway can resolve public names. They need internet access only to connect to those addresses.
What does enableDnsSupport do?
It controls whether the Amazon DNS server answers queries for the VPC. It is true by default; if it is false, instances using AmazonProvidedDNS cannot resolve any names.
What does enableDnsHostnames do?
It gives instances with public IPs public DNS hostnames and, with enableDnsSupport, lets the Amazon DNS server resolve Amazon-provided private hostnames. Private hosted zones and VPC endpoint private DNS need both attributes on.
How do I change the DNS server for EC2 instances?
Create a DHCP options set with the domain-name-servers you want (or AmazonProvidedDNS), associate it with the VPC, and renew the DHCP lease or reboot instances. For on-premises domains, prefer Route 53 Resolver forwarding rules.
Why does DNS work on the EC2 host but not in Docker containers?
Docker cannot use a loopback resolver inside containers; when the host points only at a local cache on 127.0.0.1, Docker falls back to public resolvers that a private instance cannot reach. Set "dns": ["169.254.169.253"] in /etc/docker/daemon.json and restart Docker.
Why do my private hosted zone records not resolve?
The zone is not associated with the instance's VPC, enableDnsHostnames or enableDnsSupport is off, or the instance uses custom DNS servers that do not forward to the Amazon DNS server.
What is the DNS query limit on EC2?
Each network interface can send 1,024 packets per second to link-local services, including DNS, instance metadata and time sync, combined. The limit cannot be raised; cache DNS to stay under it.
How do I flush DNS on an EC2 instance?
On Linux with systemd-resolved, run resolvectl flush-caches; on Windows, ipconfig /flushdns or Clear-DnsClientCache. Restarting a local cache such as dnsmasq also clears it.
Can I use Google DNS (8.8.8.8) on EC2?
You can, through the DHCP options set or the OS, but then AWS names, private hosted zones and VPC endpoint private DNS stop resolving, and private instances without internet access lose DNS entirely. AmazonProvidedDNS is the safer default.
How do I resolve on-premises names from EC2?
Create a Route 53 Resolver outbound endpoint and a forwarding rule for the on-premises domain, pointing at your on-premises DNS servers, and associate the rule with the VPC.
Why does nslookup work but my application cannot resolve the name?
nslookup and dig query DNS servers directly, while applications use the system resolver, which also reads the hosts file, nsswitch.conf and local caches. Check those, and the application's own DNS caching settings.
How can I see which DNS queries are failing in my VPC?
Turn on Route 53 Resolver query logging for the VPC, sending logs to CloudWatch Logs, S3 or Data Firehose. Each entry shows the query, the response code, the source instance, and any DNS Firewall action.
For readers preparing for an AWS certification
We have been covering AWS certifications alongside our fixes, so here is a short extra for readers studying for one. If you only came for the fix, you already have it; feel free to skip this part.
Exams that test this topic: Solutions Architect – Associate (SAA-C03) • CloudOps Engineer – Associate (SOA-C03) • Solutions Architect – Professional (SAP-C03 from November 17, 2026).
Here are the exam-style questions this topic tends to raise, with the reasoning you need to answer them:
1. Instances in a VPC suddenly cannot resolve any names after the VPC's DHCP options set was changed to on-premises DNS servers and the VPN went down. What restores resolution fastest?
Associate a DHCP options set that uses AmazonProvidedDNS, then renew leases or reboot.
2. Records in a Route 53 private hosted zone do not resolve from a VPC that is associated with the zone. Which VPC settings must be enabled?
Both enableDnsSupport and enableDnsHostnames.
3. A company wants instances to resolve its on-premises domain while all other names are resolved by AWS. What should it use?
A Route 53 Resolver outbound endpoint with a forwarding rule for the on-premises domain.
4. On-premises servers must resolve records in a Route 53 private hosted zone. What is needed in the VPC?
A Route 53 Resolver inbound endpoint that the on-premises DNS servers forward to.
5. Can security group rules block an instance's DNS queries to the Amazon DNS server?
No; traffic to the Amazon DNS server cannot be filtered by security groups or network ACLs.
6. A busy instance sees intermittent DNS failures. What limit is it likely hitting, and what helps?
The 1,024 packets-per-second link-local limit per network interface; cache DNS on the instance.
7. How can a security team block DNS lookups of known malicious domains from all instances in a VPC?
Route 53 Resolver DNS Firewall with a rule group associated with the VPC.
Exam codes and dates change often. Our AWS certification changes page keeps track of what is current.
By the afternoon, the client's VPC was back on AmazonProvidedDNS, a Route 53 Resolver outbound endpoint forwarded corp.example.com to the on-premises servers, and a CloudWatch alarm watched Resolver query logs for spikes in SERVFAIL responses. The VPN dropped again two weeks later. Nobody outside the network team noticed. Jake, told the story over coffee, summed it up better than the incident report: "Don't make the shop's phone book depend on the office's phone line."
📌 If you keep one line from this page
Query 169.254.169.253 directly: if it answers, fix the DHCP options set or the operating system's DNS settings; if it does not, turn on enableDnsSupport and check DNS Firewall and throttling; keep AmazonProvidedDNS as every instance's resolver and forward only internal domains with Route 53 Resolver endpoints.
No internet needed for DNS · security groups do not filter it · 1,024 packets per second per interface.
Revision note. Written October 21, 2026. We will update this page when VPC DNS or Route 53 Resolver behavior changes.