VPS Can't Resolve DNS? Fix "Temporary Failure in Name Resolution"

· 5 min read · 43 views · Getwebup

You SSH into your VPS, run apt update or curl a URL, and get slapped with "Temporary failure in name resolution." The domain records are fine, the site works from your browser — but the server itself can't look anything up. This is an OS-level DNS resolver problem, not a domain zone problem, and it's one of the more confusing errors on a fresh Linux VPS because the fix depends entirely on which resolver stack your distro is running.

Symptom

You'll see one of these, usually right after a reboot, a network config change, or moving to a new VPS image:

curl: (6) Could not resolve host: github.com
ping: google.com: Temporary failure in name resolution
E: Failed to fetch ... Temporary failure resolving 'archive.ubuntu.com'

Meanwhile ping 8.8.8.8 works fine — so the network itself is up, only name resolution is broken. That's the tell.

Why This Happens

A handful of causes account for almost every case:

  • Broken /etc/resolv.conf symlink. Modern Ubuntu/Debian manage DNS through systemd-resolved, and /etc/resolv.conf is supposed to be a symlink to a stub file it generates. If that symlink gets deleted or replaced with a static file (common after a cloud-init run or a manual edit), resolution breaks silently.
  • systemd-resolved not running. A crashed or disabled service means nothing is listening on the stub resolver at 127.0.0.53.
  • Upstream resolver unreachable. Your provider's default DNS (often the gateway IP) is down, rate-limiting you, or blocked by a network change.
  • Outbound port 53 blocked. UFW, iptables, or a cloud firewall rule that only opened 80/443/22 will silently kill DNS lookups since they ride on UDP/TCP port 53.
  • Netplan misconfiguration. A netplan YAML with no nameservers block, or a syntax error that fails silently, leaves the interface without a resolver.
  • Docker's own resolver. Containers get their DNS from the Docker daemon, not the host directly — a host-level fix doesn't always fix containers, and vice versa.

Quick Diagnosis

Run these in order — each one narrows down where the chain breaks:

CommandWhat it tells you
ping -c2 8.8.8.8Is raw network connectivity even up? If this fails too, it's not a DNS problem.
cat /etc/resolv.confIs it a symlink to /run/systemd/resolve/stub-resolv.conf, or a stale static file?
systemctl status systemd-resolvedIs the resolver service actually running?
resolvectl statusWhich DNS servers is each interface actually using?
dig google.com @8.8.8.8Does resolution work against a known-good resolver directly (bypasses local config)?
sudo ufw status verboseIs outbound port 53 allowed?

If dig @8.8.8.8 works but plain dig google.com doesn't, the problem is 100% local — broken resolv.conf, dead resolved, or a firewall rule. If even the direct query fails, it's upstream or the firewall.

On Ubuntu/Debian with systemd-resolved, check what /etc/resolv.conf actually is:

ls -la /etc/resolv.conf

If it's a regular file instead of a symlink (or points to the wrong target), fix it:

sudo rm /etc/resolv.conf
sudo ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
sudo systemctl restart systemd-resolved

Test immediately with curl -I https://github.com. This alone fixes the majority of "worked yesterday, broken today" cases after a reboot or an unattended-upgrades run.

Fix 2: Restart or Re-enable systemd-resolved

sudo systemctl enable --now systemd-resolved
sudo systemctl restart systemd-resolved
resolvectl status

If the service refuses to start, check journalctl -u systemd-resolved -n 50 for the actual error — a corrupted config in /etc/systemd/resolved.conf is the usual culprit.

Fix 3: Set Reliable Resolvers via Netplan

Provider-default DNS can be flaky, especially on budget VPS plans. Point the interface at known-good public resolvers directly. Edit your netplan file (typically /etc/netplan/50-cloud-init.yaml or similar):

network:
  version: 2
  ethernets:
    eth0:
      dhcp4: true
      nameservers:
        addresses: [1.1.1.1, 8.8.8.8]

Apply it:

sudo netplan apply

On distros without netplan (older Debian, CentOS-based systems using NetworkManager), the equivalent is setting DNS in /etc/sysconfig/network-scripts/ifcfg-eth0 (DNS1=1.1.1.1) or via nmcli con mod eth0 ipv4.dns "1.1.1.1 8.8.8.8".

Fix 4: Open Outbound Port 53

If UFW or iptables is scoped too tight, DNS gets silently dropped. For UFW:

sudo ufw allow out 53/udp
sudo ufw allow out 53/tcp
sudo ufw reload

For cloud-provider firewalls (security groups, network ACLs) check that outbound isn't restricted to a whitelist that forgot DNS — this is easy to miss when someone locks down a server following a hardening checklist and only thinks about inbound rules.

Fix 5: Docker Containers Still Failing?

Fixing the host doesn't always fix containers. If docker exec -it mycontainer ping google.com fails while the host resolves fine, restart Docker after the host fix so it re-reads /etc/resolv.conf:

sudo systemctl restart docker

Or set explicit DNS for a container/compose stack:

services:
  app:
    dns:
      - 1.1.1.1
      - 8.8.8.8

Prevention

  • Pin explicit public resolvers (1.1.1.1, 8.8.8.8, or your own) in netplan instead of relying on whatever the provider hands out over DHCP — it's one less thing that can silently rot.
  • Never hand-edit /etc/resolv.conf directly on a systemd-resolved system — edits get overwritten on the next network event and leave you confused later. Change netplan or resolved.conf instead.
  • Add a simple cron or monitoring check that alerts if dig +short getwebup.in returns empty — this catches resolver breakage before it takes down cron jobs, backups, or Let's Encrypt renewals that silently depend on working DNS.
  • After any firewall change, explicitly re-test outbound DNS, not just inbound web traffic — it's the rule people forget to verify.

Prevention Checklist

  1. Confirm /etc/resolv.conf is a symlink to the systemd-resolved stub (not a static file).
  2. Set explicit nameservers in netplan rather than trusting DHCP defaults.
  3. Allow outbound UDP/TCP 53 in every firewall layer (UFW, cloud security group).
  4. Restart Docker after any host-level DNS fix.
  5. Add a scheduled dig check so a broken resolver gets caught before certbot or cron jobs fail.

Questions people actually ask