/etc/hosts and /etc/resolv.conf - Understanding DNS Resolution Priority

/etc/hosts and /etc/resolv.conf - Understanding DNS Resolution Priority

What Are /etc/hosts and /etc/resolv.conf?

/etc/hosts is a static local file that maps hostnames to IP addresses without involving DNS. /etc/resolv.conf configures the DNS resolver, specifying which nameservers to query. The resolution order — which source is checked first — is controlled by the hosts: line in /etc/nsswitch.conf. The default is files dns, meaning the hosts file takes priority over DNS.

Quick Summary

Resolution order for hosts: files dns:

  1. Check /etc/hosts — if a match is found, return immediately
  2. Query DNS nameservers from /etc/resolv.conf

How Does Name Resolution Work?

Linux name resolution is managed by NSS (Name Service Switch). The /etc/nsswitch.conf file lists resolution sources in priority order under the hosts: entry.

$ grep ^hosts /etc/nsswitch.conf
hosts:          files mdns4_minimal [NOTFOUND=return] dns
  • files = /etc/hosts
  • mdns4_minimal = mDNS (Avahi) for .local domains
  • dns = nameservers defined in /etc/resolv.conf

Resolution flow:

Application calls getaddrinfo("example.com")
    ↓
1. Search /etc/hosts
   → Match found: return that IP immediately
   → No match: continue
    ↓
2. Query DNS resolver (nameserver in /etc/resolv.conf)
   → Return response

/etc/hosts Format and Usage Patterns

File format

IP-address  hostname  [aliases ...]
$ cat /etc/hosts
127.0.0.1   localhost
127.0.1.1   myhost.local myhost
::1         localhost ip6-localhost ip6-loopback

Redirecting a domain to localhost for development

A common pattern when testing against a production domain locally:

# Redirect example.com to local development server
127.0.0.1   example.com
127.0.0.1   api.example.com

Blocking unwanted domains

Pointing a domain to 0.0.0.0 prevents connections from reaching it:

0.0.0.0     ads.example.com

Changes to /etc/hosts take effect immediately — no DNS cache flush needed.

/etc/resolv.conf Settings

Key directives

Directive Purpose
nameserver IP address of DNS server to query (up to 3)
search Domain suffixes appended to bare hostnames (db01db01.example.com)
domain Single-domain version of search (legacy)
$ cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
search example.com

Ubuntu note — systemd-resolved

On Ubuntu 20.04 and later, /etc/resolv.conf is often a symlink to a stub managed by systemd-resolved:

$ ls -la /etc/resolv.conf
lrwxrwxrwx 1 root root 39 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

Editing the symlink target directly will be overwritten on the next reboot. Use resolvectl instead:

# Show current DNS configuration
$ resolvectl status

# Set DNS for a specific interface
$ resolvectl dns eth0 8.8.8.8

Check whether /etc/resolv.conf is a symlink with ls -la /etc/resolv.conf before editing it. If it is a symlink, use resolvectl instead of editing directly.

Controlling Priority with /etc/nsswitch.conf

Edit the hosts: line in /etc/nsswitch.conf to change the resolution order:

# Default on Ubuntu
hosts: files mdns4_minimal [NOTFOUND=return] dns

# Query DNS first (uncommon)
hosts: dns files

Changing the hosts: line affects name resolution for all applications on the system. Record the original value before making changes.

Debugging Name Resolution

getent hosts — resolves through nsswitch.conf

dig and nslookup query DNS directly, bypassing /etc/hosts. Use getent hosts when you need to confirm what the OS actually resolves.

# Resolve using the full nsswitch.conf chain (including /etc/hosts)
$ getent hosts example.com
93.184.216.34   example.com

# Verify a /etc/hosts entry is working
$ getent hosts myapp.local
127.0.0.1   myapp.local
# DNS only (bypasses /etc/hosts)
$ dig example.com
$ nslookup example.com

# Full resolution chain (includes /etc/hosts)
$ getent hosts example.com

resolvectl — inspect systemd-resolved state

# Show DNS servers and search domains per interface
$ resolvectl status

# Test resolution for a specific domain
$ resolvectl query example.com

Practical Scenarios

Scenario 1: Point a production domain to localhost

# Add entry to /etc/hosts
$ sudo sh -c 'echo "127.0.0.1 api.myapp.com" >> /etc/hosts'

# Verify
$ getent hosts api.myapp.com
127.0.0.1   api.myapp.com

Remove the entry after testing:

$ sudo sed -i '/api.myapp.com/d' /etc/hosts

Scenario 2: Switch to a custom DNS server

For environments where /etc/resolv.conf is not managed by systemd-resolved:

$ sudo nano /etc/resolv.conf
# Add or change
nameserver 1.1.1.1   # Cloudflare DNS
nameserver 8.8.8.8   # Google DNS

Verify:

$ dig @1.1.1.1 example.com

Summary — Name Resolution Quick Reference

Check Command
Resolution order grep ^hosts /etc/nsswitch.conf
Hosts file contents cat /etc/hosts
DNS resolver config cat /etc/resolv.conf
Check if resolv.conf is a symlink ls -la /etc/resolv.conf
DNS settings (Ubuntu) resolvectl status
Test resolution including hosts getent hosts <domain>
Test DNS only dig <domain>

Common troubleshooting

  • getent hosts resolves but dig / nslookup does not → entry exists in /etc/hosts
  • Neither resolves → DNS configuration or resolv.conf issue
  • Ubuntu: /etc/resolv.conf edits lost after reboot → managed by systemd-resolved; use resolvectl to make persistent changes

Next Reading