What you're seeing
$ ssh [email protected]
ssh: Could not resolve hostname example.com: Name or service not knownVariants you might see:
Could not resolve hostname X: Temporary failure in name resolution— DNS resolver reachable but timing outCould not resolve hostname X: No address associated with hostname— DNS resolved, but no A/AAAA record existsCould not resolve hostname X: nodename nor servname provided, or not known— macOS variant of the same thing
All of these are DNS failures on your side, not SSH failures.
What's causing this error
The TCP connection never gets attempted. Before SSH tries to connect, your OS asks its configured resolver: "what IP is example.com?" That lookup is failing. The five real causes:
- Typo in the hostname. Trivial but surprisingly common —
excample.com,example.co(trailing-character drop),git.example.con. - Resolver unreachable. Your
/etc/resolv.confpoints at a DNS server that's down, throttling you, or behind a firewall. - Wrong
/etc/hostsentry. An old manual entry overrides the real DNS, pointing at an IP that no longer matches the name. - VPN / captive portal interference. Some VPNs replace your DNS resolver but block split-tunnel lookups. Hotel/airport networks force a captive portal that hijacks DNS until you log in.
- The hostname genuinely doesn't have a DNS record. Server moved, domain expired, internal hostname only resolvable inside a VPN.
How to fix it
Step 1: Confirm it's DNS, not SSH
Try connecting by IP instead. If you have the IP:
- Works → confirmed DNS issue. Go to step 2.
- Same kind of error or different network error → the issue isn't only DNS; check connection refused / no route to host paths.
Step 2: Test the lookup directly
$ dig +short example.com
$ getent hosts example.comWhat each result means:
- Returns an IP → your tools can resolve, but
sshcan't — different resolver paths. Check your/etc/nsswitch.confor app-specific DNS config. - Returns nothing / timeout → resolver is broken. Go to step 3.
- Returns the wrong IP → check
/etc/hostsfor an overriding entry.
Step 3: Check your resolver configuration
$ cat /etc/resolv.conf
$ cat /etc/hosts | grep -i example
# If using systemd-resolved:
$ resolvectl status | head -20The lines to look for:
nameserver 8.8.8.8(or similar) — that's your DNS server. If it's blank, weird IP, or unreachable, that's the problem.- A
127.0.0.1 example.comor any stale entry in/etc/hostsfor the hostname you're connecting to.
Step 4: Reset DNS if it's broken
# Restart systemd-resolved (most modern distros):
$ sudo systemctl restart systemd-resolved
# Or restart NetworkManager:
$ sudo systemctl restart NetworkManagerStep 5: VPN / captive portal check
If you're on a VPN: temporarily disconnect and retry. If it works without VPN, the VPN is intercepting your DNS — usually fixed by enabling split-tunnel DNS for the target domain, or by using the VPN's internal DNS server.
If you're on hotel / airport / coffee shop Wi-Fi: open any web page first. Captive portals block DNS until you've authenticated.
Common edge cases
| Situation | What's actually wrong |
|---|---|
ssh fails, but ping and curl work | ssh uses a different resolution path on some systems (NSS); fix /etc/nsswitch.conf hosts: line |
| Works at home, fails on corporate Wi-Fi | Corporate DNS doesn't resolve external hostnames; use the IP or set up a host-specific resolver |
| Worked yesterday | DNS record changed or expired — dig to confirm the new IP, update ~/.ssh/config if you hardcoded the old one |
| Works from terminal, fails from a script | The script's environment is missing the resolver config — particularly PATH or DNS_SERVER env vars in some scripted contexts |
Internal *.local or *.internal hostnames fail | These usually require VPN connection or mDNS; if you're remote, you need to be on the VPN first |
Temporary failure in name resolution repeats every time | Resolver is fully unreachable — your /etc/resolv.conf was overwritten by a stale DHCP lease or VPN client. Restart networking. |