Quick fix: run ping -c1 1.1.1.1. If the IP answers but names fail, the network is fine and the resolver is broken: check ls -l /etc/resolv.conf and, on systemd-resolved systems, resolvectl status, then set the nameservers where your system manages them (netplan, NetworkManager, ifupdown) instead of hand-editing a generated file. If the IP does not answer either, the problem is routing or a firewall, not DNS.
ping: example.com: Temporary failure in name resolution means the server could not turn a name into an IP address. The same failure shows up as curl: (6) Could not resolve host: example.com, as apt’s Temporary failure resolving 'deb.debian.org', and inside Docker builds. “Temporary” is the resolver library’s word for “no nameserver gave me an answer” — it does not mean the problem will go away on its own.
On Windows the same failure is reported as “DNS server not responding”; the fixes for that side are in DNS server not responding.
Is it DNS or the whole network?
Four commands separate the two cases in under a minute:
ip -br addr # does the interface have an address?
ip route # is there a "default via ..." line?
ping -c1 1.1.1.1 # can packets leave the server?
getent hosts example.com # can names be resolved the way programs do it?- No address or no default route — the network configuration itself is broken, and no DNS change will help. Fix the interface first, from the console if SSH is down.
- Route present, but the IP does not answer — something blocks outbound traffic: a firewall on the server, upstream filtering, or the wrong gateway. Some networks drop ping;
curl -sI https://1.1.1.1is a second test that needs no DNS. - The IP answers, getent prints nothing — this is a resolver problem. Read on.
If dig or nslookup is installed, ask a public resolver directly: dig @1.1.1.1 example.com +short. An answer there, while a plain lookup fails, proves the configured nameserver is the problem. On a broken box these tools are often missing, and with DNS down you cannot install them — which is why the four commands above use nothing beyond the base system.
What is in /etc/resolv.conf, and who writes it?
Programs read their nameservers from /etc/resolv.conf. On almost every modern system that file is generated, and the first step is finding out by what:
ls -l /etc/resolv.conf
cat /etc/resolv.conf- A symlink to
../run/systemd/resolve/stub-resolv.confwithnameserver 127.0.0.53— systemd-resolved owns DNS. Ubuntu works this way by default. Fix it in resolved or netplan. - A plain file starting with
# Generated by NetworkManager— NetworkManager writes it, as on Rocky, AlmaLinux and RHEL. Fix it withnmcli. - A plain file with a resolvconf or DHCP header — resolvconf, a DHCP client or cloud-init writes it. Fix it at that source.
- Empty, or no
nameserverlines — a botched edit, or the tool that should write it failed. - A symlink whose target does not exist —
catsaysNo such file or directory. Typically systemd-resolved was stopped or removed and left its link behind.
Which servers to put back? Any reliable public resolver works; the examples here use Cloudflare (1.1.1.1) and Quad9 (9.9.9.9). On a VMHeaven VPS those two are also what cloud-init sets at installation and on every reinstall, so putting them back restores the values the server started with.
How do I fix it on Ubuntu (systemd-resolved and netplan)?
Start with what resolved itself thinks:
resolvectl status # DNS servers per interface, and globally
systemctl status systemd-resolved # is the stub resolver running at all?
sudo systemctl enable --now systemd-resolved # if it is notIf an interface lists no DNS servers, or ones that do not answer, set them in netplan, under the interface that carries your traffic (ip -br link shows its name):
network:
version: 2
ethernets:
eth0:
# keep the existing addresses, routes and dhcp4 lines as they are
nameservers:
addresses: [1.1.1.1, 9.9.9.9]sudo netplan try # rolls back after 120 seconds unless you confirm
sudo netplan apply
resolvectl statusIf the file is called 50-cloud-init.yaml, cloud-init generated it, and its header says so: changes may not persist, and the documented way to stop cloud-init managing the network is a file /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg containing network: {config: disabled}. Alternatively, leave netplan alone and give resolved global servers, which apply on top of the per-interface ones:
sudo mkdir -p /etc/systemd/resolved.conf.d
printf '[Resolve]\nDNS=1.1.1.1 9.9.9.9\n' | sudo tee /etc/systemd/resolved.conf.d/dns.conf
sudo systemctl restart systemd-resolved
resolvectl flush-cachesFor a quick test that does not survive a restart, sudo resolvectl dns eth0 1.1.1.1 9.9.9.9 sets servers on one interface immediately.
What about Debian 12 and 13?
Debian does not pick one network stack for you; it uses whatever the installer or the image chose. Find out which one you have:
systemctl is-active systemd-resolved NetworkManager systemd-networkd networking
ls /etc/netplan/ /etc/network/interfaces.d/ 2>/dev/null- systemd-resolved is active — the Ubuntu section above applies, including netplan if
/etc/netplanhas files. - Classic ifupdown (
networkingis active) — adns-nameservers 1.1.1.1 9.9.9.9line under the interface in/etc/network/interfacesonly takes effect when theresolvconfpackage is installed. Without it, a static configuration leaves/etc/resolv.confas a plain file, and editing it directly is correct. Withinet dhcp, the DHCP client rewrites it on every lease; on Debian 12 that is dhclient, wheresupersede domain-name-servers 1.1.1.1, 9.9.9.9;in/etc/dhcp/dhclient.confkeeps your servers. - NetworkManager is active — use the
nmclicommands from the RHEL section below.
nameserver 1.1.1.1
nameserver 9.9.9.9How do I set DNS servers on Rocky, AlmaLinux and RHEL 9?
NetworkManager writes /etc/resolv.conf here, and it overwrites hand edits. Set DNS on the connection instead:
nmcli -t -f NAME,DEVICE con show --active # find the connection name
sudo nmcli con mod "System eth0" ipv4.dns "1.1.1.1 9.9.9.9" ipv4.ignore-auto-dns yes
sudo nmcli con up "System eth0"
cat /etc/resolv.confReplace System eth0 with the name the first command printed; on cloud images it is often cloud-init eth0. ipv4.ignore-auto-dns yes stops DHCP-supplied servers from being added back. Re-activating the connection you are logged in through usually survives, but keep a console open in case it does not.
How do I keep my DNS servers on Alpine?
With DHCP, Alpine’s udhcpc rewrites /etc/resolv.conf on every lease. To keep your own servers, tell it to leave the file alone, then write it yourself:
mkdir -p /etc/udhcpc
echo 'RESOLV_CONF="no"' >> /etc/udhcpc/udhcpc.conf
printf 'nameserver 1.1.1.1\nnameserver 9.9.9.9\n' > /etc/resolv.confWith a static configuration nothing rewrites the file, and a direct edit is the fix.
How do I fix sudo: unable to resolve host?
sudo: unable to resolve host myserver: Name or service not known is a different problem with similar words. sudo looks up the machine’s own hostname, and that name is missing from /etc/hosts — typically right after hostnamectl set-hostname. sudo still runs the command; it just warns, and may hang for a few seconds first.
hostname # the name sudo is looking for
grep -w "$(hostname)" /etc/hosts # no output = missing
echo "127.0.1.1 $(hostname)" | sudo tee -a /etc/hosts127.0.1.1 is the Debian and Ubuntu convention; on RHEL-family systems, adding the name to the 127.0.0.1 line works the same. A VPS with a fixed public address and a fully qualified domain name can map the real IP instead, full name first: 203.0.113.10 web01.example.com web01. If /etc/hosts starts with a cloud-init notice about manage_etc_hosts, it is regenerated at boot: change the template it names under /etc/cloud/templates/ instead, or your edit disappears.
Why does DNS fail inside Docker but work on the host?
Containers do not use the host’s resolver directly, and which servers they get depends on the network they are attached to:
- The default bridge (a plain
docker run) gets a copy of the host’s/etc/resolv.confwith loopback addresses removed, because127.0.0.53inside a container would point at the container itself. When the host uses the systemd-resolved stub, Docker reads the real upstream servers from/run/systemd/resolve/resolv.confinstead. If no usable server is left, it falls back to Google’s8.8.8.8and8.8.4.4— which fails on any network that blocks outside resolvers. - User-defined networks, including every Docker Compose project, use Docker’s embedded DNS server at
127.0.0.11, which resolves container names and forwards everything else to the host’s configured servers.
docker run --rm busybox cat /etc/resolv.conf # which servers did it get?
docker run --rm busybox nslookup example.com # does resolution work?
docker run --rm busybox ping -c1 1.1.1.1 # or is all outbound traffic broken?Pin the servers for every container in the daemon configuration:
{
"dns": ["1.1.1.1", "9.9.9.9"]
}sudo systemctl restart docker
# per container instead: docker run --dns 1.1.1.1 ...
# in Compose: a "dns:" list under the serviceIf even ping 1.1.1.1 fails from a container while it works on the host, DNS is only the first symptom: forwarding or Docker’s NAT rules are gone. Check that sysctl net.ipv4.ip_forward prints 1, and if a firewall reload flushed the rules, sudo systemctl restart docker recreates them.
Is a firewall blocking outbound DNS?
DNS uses port 53 over UDP, and over TCP for large answers. A firewall with a default-deny outgoing policy blocks it unless you allow it explicitly:
sudo ufw status verbose # look at "Default: ... (outgoing)"
sudo ufw allow out 53 # UDP and TCP
sudo iptables -S OUTPUT # a DROP policy or rule here blocks it tooUFW allows all outgoing traffic by default, and the UFW setup guide keeps it that way on purpose. If you did lock outgoing traffic down, DNS is the first thing to break.
What else causes Temporary failure in name resolution?
- Only IPv6 nameservers, no IPv6 route. If
resolv.conflists only IPv6 addresses and the server has no working IPv6 connectivity, every lookup times out. Add an IPv4 resolver. - A nameserver from the old network. A server moved or cloned from another host can carry the previous provider’s internal resolver, which no longer answers from the new network.
/etc/nsswitch.confwithoutdns. If thehosts:line lists onlyfiles, nothing ever asks a nameserver.
If curl itself is missing rather than failing with error 6, that is a different fix: curl: command not found. And if your server resolves fine but your domain does not point at it, that is the opposite problem, covered in pointing a domain at your VPS.
When networking is broken completely, SSH goes with it. The VNC console in the VMHeaven panel connects to the machine’s screen rather than over the network, so every KVM VPS can still be fixed from there — the same way out as when SSH refuses connections.
Frequently asked
Why does ping 8.8.8.8 work but ping google.com fail?
Pinging an IP address needs no DNS. If addresses answer but names do not, the network is fine and the resolver configuration is broken — check /etc/resolv.conf and, on systemd-resolved systems such as Ubuntu, 'resolvectl status'.
Why do my /etc/resolv.conf edits vanish after a reboot?
The file is generated — by systemd-resolved, NetworkManager, a DHCP client, resolvconf or cloud-init — and rewritten at boot or on lease renewal. Set the nameservers in the tool that owns it: netplan or resolved.conf, nmcli, dhclient.conf or udhcpc.conf.
How do I fix 'sudo: unable to resolve host'?
The machine's own hostname is missing from /etc/hosts. Add a line such as '127.0.1.1 myserver', using the name the 'hostname' command prints. sudo still runs the command; the warning only delays it.
Why do Docker containers fail DNS when the host works?
Containers cannot use a loopback resolver such as 127.0.0.53, so Docker substitutes upstream servers and, if none are left, falls back to 8.8.8.8 and 8.8.4.4 — which fails where those are blocked. Set "dns" in /etc/docker/daemon.json and restart Docker.