/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:
- Check
/etc/hosts— if a match is found, return immediately - 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/hostsmdns4_minimal= mDNS (Avahi) for.localdomainsdns= 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 (db01 → db01.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 hostsresolves butdig/nslookupdoes not → entry exists in/etc/hosts- Neither resolves → DNS configuration or
resolv.confissue - Ubuntu:
/etc/resolv.confedits lost after reboot → managed bysystemd-resolved; useresolvectlto make persistent changes