SSH Debugging: A Layer-by-Layer Guide
known_hosts when the actual issue was a DNS fluke. In a production environment, treating every error as a timestamp of how far the connection actually progressed is the only way to stop the guessing game.If you get a Could not resolve hostname error, your key is irrelevant because the client hasn't even attempted a TCP handshake. You can't authenticate with a server you can't find.
The 7-Stage Connection Pipeline
To debug this systematically, I map every attempt to these checkpoints:
configuration → name resolution → TCP connection → SSH transport/key exchange → server verification → user authentication → channel creation
If you fail at stage 2, no amount of prompt engineering for your config or key regeneration will fix it.
Stage 0: Configuration Resolution
Before a single packet hits the wire, the client merges your CLI flags with ~/.ssh/config and system defaults.
A common point of confusion is how SSH handles aliases. If you have:
Host lab-*
User devRunning ssh lab-gpu sets the user to dev, but it doesn't provide an IP. Unless there's a HostName directive, the OS has to resolve lab-gpu. To stop guessing which config block is actually winning (since "most specific" isn't always how it works), use this command to see the final derived config:
ssh -G demo-server | grep -E '^(hostname|user|port|identityfile) 'If the hostname or identity file listed here is wrong, you're facing a config issue, not a network issue.
Stage 1: OS Hostname Resolution
Once the config is parsed, the OS takes over to turn that hostname into an IP via DNS, /etc/hosts, or VPN resolvers.
A frequent friction point in our AI workflow deployments is the confusion between tool inventories (like Ansible) and the system resolver. Just because a server is in an Ansible inventory doesn't mean OpenSSH knows where it is.
If you see Could not resolve hostname, the packet never left your machine. To verify what the system actually sees, skip SSH entirely and use:
getent hosts server.example.comOn macOS, I use:
dscacheutil -q host -a name server.example.comIf these return nothing, your problem is DNS or your /etc/hosts file, and you can stop messing with your .pub keys.
