Why Doesn’t the Linux ‘host’ Command Resolve Entries from /etc/hosts?


1 views

Many Linux administrators encounter this puzzling behavior: while applications like telnet, ping, and web browsers correctly resolve entries from /etc/hosts, the host command stubbornly returns NXDOMAIN errors. Let's dissect why this happens and how to work around it.

The Linux name resolution process involves multiple components:

Application → glibc (nsswitch) → DNS resolver (hosts file/DNS)

The key difference lies in how different tools access this stack:

# Traditional apps use glibc resolver
$ ping puppetmaster  # Uses /etc/hosts via glibc

# host/nslookup bypass glibc
$ host puppetmaster  # Direct DNS query

Your /etc/nsswitch.conf controls resolution order. A typical configuration:

hosts: files dns

This means "check /etc/hosts first, then DNS". However, host and nslookup bypass this system entirely.

Option 1: Use getent (glibc-aware)

$ getent hosts puppetmaster
10.248.27.66  ec2-50-112-220-110.us-west-2.compute.amazonaws.com puppetmaster

Option 2: Query hosts file directly

$ grep -w puppetmaster /etc/hosts
10.248.27.66 ec2-50-112-220-110.us-west-2.compute.amazonaws.com puppetmaster

Option 3: Use dig with +short

$ dig +short puppetmaster A @10.248.27.66

If you're stuck with host for scripting, force local resolution:

$ host puppetmaster 127.0.0.1
Using domain server:
Name: 127.0.0.1
Address: 127.0.0.1#53
Aliases:

puppetmaster has address 10.248.27.66
  • Always include both shortname and FQDN in entries
  • Consider using DNSMasq for local caching
  • Document all manual /etc/hosts entries

When debugging network connectivity on an Ubuntu 12.04 system, I encountered this puzzling behavior:

# /etc/hosts entry
10.248.27.66 ec2-50-112-220-110.us-west-2.compute.amazonaws.com puppetmaster

# Failing resolution
$ host puppetmaster
Host puppetmaster not found: 3(NXDOMAIN)

# Successful connection
$ telnet puppetmaster 8140
Trying 10.248.27.66...
Connected to ec2-50-112-220-110.us-west-2.compute.amazonaws.com.

Linux systems follow a specific order when resolving hostnames:

  1. Local files (/etc/hosts, /etc/nsswitch.conf)
  2. DNS (configured in /etc/resolv.conf)
  3. NIS/NIS+ (if configured)

The key difference between host and other utilities like telnet lies in how they interact with this resolution stack.

The host command is a DNS-specific utility that queries nameservers directly, completely bypassing the local resolution mechanism. It ignores:

  • /etc/hosts file
  • nsswitch.conf configuration
  • Local naming services

This explains why our entry wasn't found, while telnet (which uses the system's resolver libraries) worked perfectly.

To confirm this behavior, try these resolution methods:

# Using getent (respects all resolution methods)
$ getent hosts puppetmaster
10.248.27.66    ec2-50-112-220-110.us-west-2.compute.amazonaws.com puppetmaster

# Using ping (uses system resolver)
$ ping -c 1 puppetmaster
PING ec2-50-112-220-110.us-west-2.compute.amazonaws.com (10.248.27.66) 56(84) bytes of data.

If you must use host but want to include local entries, you can:

# Set up a local DNS server (like dnsmasq)
$ sudo apt-get install dnsmasq
$ echo "address=/puppetmaster/10.248.27.66" | sudo tee -a /etc/dnsmasq.conf
$ sudo service dnsmasq restart

# Then query your local DNS
$ host puppetmaster 127.0.0.1
puppetmaster has address 10.248.27.66

For consistent behavior across all tools:

  1. Prefer standard utilities like ping, getent hosts, or nslookup
  2. Understand each tool's resolution behavior before debugging
  3. Modify /etc/nsswitch.conf if you need to adjust resolution order

Example nsswitch.conf modification:

hosts: files dns
# This means "try /etc/hosts first, then DNS"