LinuxLinux

sudo: unable to resolve host

sudo cannot resolve the machine's own hostname, so every command pauses. A one-line fix in /etc/hosts, and how to make it stick in containers and cloud images.

easy fix5 min read

the linux error
sudo: unable to resolve host myserver: Name or service not known

sudo: unable to resolve host 3f2c1a9e4b7d: Temporary failure in name resolution

sudo: unable to resolve host ip-10-0-1-42

Do this first3 steps

Run these in order. Each one tells you what its output means before you change anything.

  1. 1

    Compare the system hostname against what /etc/hosts knows

    hostname && grep -nE "127\.0\.[01]\.1" /etc/hosts

    If the name printed by hostname does not appear on a 127.0.0.1 or 127.0.1.1 line, sudo cannot resolve it. That mismatch is the entire cause.

  2. 2

    Add the hostname to the loopback entry

    printf '127.0.1.1\t%s\n' "$(hostname)" | sudo tee -a /etc/hosts

    Debian and Ubuntu use 127.0.1.1 for the machine's own name, keeping it distinct from localhost. Red Hat family systems put the name on the 127.0.0.1 line instead. Either resolves it.

  3. 3

    Verify sudo is no longer warning

    sudo -n true 2>&1 | grep -q "resolve host" && echo "STILL BROKEN" || echo "resolved"

    The warning is cosmetic in the sense that sudo still runs the command, but it also adds a DNS timeout to every invocation, which is what makes an affected machine feel slow.

All 8 sections

sudo resolves the local hostname when it starts, for logging and for matching host patterns in /etc/sudoers. If the name does not resolve, it prints this warning and carries on. The command still runs.

It is worth fixing anyway, because the resolution attempt goes out to DNS and times out, adding a delay to every sudo invocation. On a machine where that is a second or two, it makes everything feel broken.

Confirm it

hostname
grep -nE "127\.0\.[01]\.1" /etc/hosts
myserver
1:127.0.0.1	localhost

myserver appears nowhere. That is the whole bug.

The fix

printf '127.0.1.1\t%s\n' "$(hostname)" | sudo tee -a /etc/hosts

Resulting in:

127.0.0.1	localhost
127.0.1.1	myserver

Debian and Ubuntu use 127.0.1.1 for the machine's own name, deliberately separate from localhost, so that software resolving the hostname does not get an entry shared with everything else on loopback. Red Hat family systems conventionally put the name on the 127.0.0.1 line:

127.0.0.1	localhost myserver

Either resolves the warning. Follow whichever your distribution uses.

How the mismatch happens

The hostname was changed without updating /etc/hosts. Use hostnamectl, which is persistent, rather than hostname, which is not:

sudo hostnamectl set-hostname myserver
sudo sed -i "s/^127\.0\.1\.1.*/127.0.1.1\tmyserver/" /etc/hosts

hostname myserver alone changes it until the next reboot and touches nothing else, which is how a machine ends up in this state after a reboot with no obvious cause.

A container. Docker sets the hostname to the container id and writes a matching /etc/hosts entry, so this is usually fine. It breaks when a Dockerfile runs sudo at build time, because the build container's hostname differs from what any baked-in /etc/hosts says.

Build images that do not need sudo at all: RUN already executes as root by default, so RUN sudo apt-get install ... is both unnecessary and a source of this error. Drop the sudo.

Where a container genuinely needs it at runtime:

docker run --hostname myserver --add-host myserver:127.0.0.1 myapp

A cloud instance that renamed itself. cloud-init sets the hostname from instance metadata at boot. Setting a hostname manually is then reverted on the next boot, and /etc/hosts no longer matches:

# /etc/cloud/cloud.cfg
preserve_hostname: true

Or set it properly through cloud-init rather than fighting it:

#cloud-config
hostname: myserver
fqdn: myserver.internal.acme.com
manage_etc_hosts: true

manage_etc_hosts: true makes cloud-init maintain the entry for you, which is the durable answer on an image you will build many instances from.

FQDN and the trailing details

If /etc/sudoers uses host patterns, or logs need the fully qualified name, list both:

127.0.1.1	myserver.internal.acme.com	myserver

The FQDN goes first. hostname -f returns the first name on the matching line, so the order is not cosmetic.

hostname          # myserver
hostname -f       # myserver.internal.acme.com

Not just sudo

Anything resolving the local hostname is affected, and the failures are less obvious:

  • Java's InetAddress.getLocalHost() throws UnknownHostException, which takes down applications at startup.
  • Postgres and some other daemons fail to bind or log warnings.
  • Kerberos and anything doing host-based authentication fails.

So a broken /etc/hosts presents as several unrelated-looking problems on the same machine, and this warning is often the earliest visible sign.

The nsswitch ordering

grep '^hosts:' /etc/nsswitch.conf
hosts: files dns myhostname

files first means /etc/hosts wins. myhostname is an nss module from systemd that resolves the local hostname even without an /etc/hosts entry, which is why some systemd-based systems never show this error. If the ordering puts dns before files, a slow or wrong DNS answer takes precedence over your local entry, which is worth fixing in its own right.

A checklist

  1. hostname, then grep /etc/hosts for that name.
  2. Absent → add a 127.0.1.1 <hostname> line, or append it to the 127.0.0.1 line on RHEL.
  3. Change hostnames with hostnamectl set-hostname, not hostname.
  4. Update /etc/hosts in the same step, every time.
  5. Docker builds → remove sudo from RUN; it already runs as root.
  6. Cloud instances → preserve_hostname: true, or let cloud-init manage it.
  7. FQDN first on the line, short name second.
  8. Check hosts: ordering in /etc/nsswitch.conf puts files before dns.

Frequently Asked Questions

Is "unable to resolve host" actually breaking anything?

sudo still runs your command, so in the narrow sense it is only a warning. The real cost is the delay: sudo attempts the lookup, and with no local entry that goes out to DNS and waits for a timeout on every single invocation. On a machine where that timeout is a second or two, every sudo command feels sluggish and scripted work slows noticeably. It is also an early warning that other software resolving the local hostname, such as JVMs calling getLocalHost(), will fail less gracefully.

What is 127.0.1.1 and why not just use 127.0.0.1?

Debian and Ubuntu use 127.0.1.1 for the machine's own hostname specifically to keep it distinct from localhost on 127.0.0.1. The separation means software resolving the system's name gets an address of its own rather than one shared with every other loopback service, which matters for daemons that bind or filter by resolved address. Red Hat family distributions take the other approach and append the hostname to the 127.0.0.1 line. Both work; follow whichever your distribution already uses.

Why does my hostname keep reverting after a reboot?

Either it was set with hostname, which only changes the running value and does not persist, or cloud-init is resetting it from instance metadata at boot. Use hostnamectl set-hostname for a persistent change on a normal machine. On a cloud instance, set preserve_hostname: true in /etc/cloud/cloud.cfg to stop cloud-init overriding you, or better, configure the hostname through cloud-init itself with manage_etc_hosts: true so the /etc/hosts entry is maintained alongside it.

Why does this happen in my Docker build?

Because a RUN step invoked sudo and the build container's hostname does not match anything in the image's /etc/hosts. The deeper point is that sudo should not be there at all: RUN executes as root by default, so RUN sudo apt-get install ... is redundant and introduces this failure for no benefit. Remove the sudo from build steps. If a container genuinely needs it at runtime, pass --hostname and --add-host when you run it.

What else breaks when the hostname does not resolve?

Anything that calls the resolver for the machine's own name. Java's InetAddress.getLocalHost() throws UnknownHostException, which can stop an application starting entirely. Some daemons fail to bind or emit warnings at startup, and Kerberos and other host-based authentication fails outright. Because these look like unrelated faults on the same host, the sudo warning is worth treating as a signal about the machine rather than a cosmetic annoyance about one command.

Reference and practice

Learn the underlying concept

Other Linux errors