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:
- Local files (/etc/hosts, /etc/nsswitch.conf)
- DNS (configured in /etc/resolv.conf)
- 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:
- Prefer standard utilities like
ping
,getent hosts
, ornslookup
- Understand each tool's resolution behavior before debugging
- 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"