Network administrators and macOS developers migrating between corporate VPNs, local Docker containers, and public Wi-Fi networks frequently encounter baffling DNS resolution discrepancies. A domain might resolve perfectly inside a terminal ping command yet fail in web browsers, or vice versa. Looking into /etc/resolv.conf often compounds the confusion, as macOS displays a disclaimer that the file is automatically generated and not used by the native OS resolver.
macOS manages DNS resolution dynamically through its unified System Configuration framework (configd), supporting multiple concurrent network interfaces, split-tunnel VPN routing, and per-domain resolver scopes. To inspect the true active DNS routing table in macOS, Apple provides the scutil –dns command. This guide explains how to read and diagnose macOS DNS configurations using scutil.
Why /etc/resolv.conf is Misleading on macOS
In traditional Linux environments, standard C libraries query /etc/resolv.conf directly. In macOS:
- macOS delegates DNS lookups to the central system daemon
mDNSResponder. /etc/resolv.confexists solely as a compatibility shim for legacy Unix command-line utilities.- macOS evaluates DNS requests hierarchically based on scoped interface configurations, domain name matching rules, and active VPN routing policies.
Executing the scutil –dns Command
Open Terminal and run the native configuration inspection command:
scutil --dns
Deconstructing scutil –dns Output
The command produces a structured list of configured DNS resolvers, grouped into two primary sections: Global Resolvers and Scoped / Per-Interface Resolvers.
1. DNS Configuration (Global Scopes)
The initial section lists resolvers used for standard, non-scoped domain queries:
DNS configuration
resolver #1
nameserver[0] : 1.1.1.1
nameserver[1] : 1.0.0.1
if_index : 6 (en0)
flags : Request A records, Request AAAA records
reach : 0x00020002 (Reachable, Directly Reachable Address)
In this block, resolver #1 points to Cloudflare DNS via hardware interface en0 (Wi-Fi), indicating the default outbound path for general internet traffic.
2. Scoped and VPN Split-Tunnel Resolvers
Below the global resolvers, scutil --dns details scoped configurations reserved for specific internal domain suffixes or active VPN tunnels:
resolver #2
domain : corp.internal
nameserver[0] : 10.200.0.53
if_index : 12 (utun3)
flags : Scoped, Request A records
reach : 0x00000002 (Reachable)
Here, queries ending in .corp.internal are automatically routed to internal nameserver 10.200.0.53 over virtual VPN adapter utun3, while all other public internet traffic continues traversing the global resolver.
Diagnostic Troubleshooting Scenarios
1. Detecting DNS Search Domain Hijacking
Inspect the search domain lines under resolver #1. If an unrecognised local Wi-Fi router injects rogue search suffixes (e.g. search domain[0] : localdomain), single-word internal hostnames or local development sites may resolve to external ad pages.
2. Verifying MDNS and Bonjour Resolution
Look for resolvers configured with domain : local and options : mdns. This confirms that Multicast DNS is actively bound to discover local Apple devices, printers, and AirPlay targets on your subnet.
3. Flushing the Resolver Cache
If you modify network DNS settings in System Settings or disconnect from a VPN, stale DNS mappings can linger in memory. Flush the active cache cleanly via terminal:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
macOS DNS Diagnostic Commands Comparison
| Command | Query Mechanism | What It Actually Tests |
|---|---|---|
scutil --dns |
configd System Framework | Actual OS routing tables, split-tunnel VPN rules, and interface priority |
dscacheutil -q host -a name example.com |
mDNSResponder Native API | Tests exactly what macOS apps (Safari, Chrome) receive from the system resolver |
dig example.com |
Direct Socket Query | Queries the nameserver listed in /etc/resolv.conf; bypasses macOS resolver rules |