The client side: ssh -v
ssh -v user@server
A connection goes through stages in a fixed order. Find the last stage that appears in the output, and you know where the trouble is.
1. Reading the config
debug1: OpenSSH_10.3p1, LibreSSL 3.3.6
debug1: Reading configuration data /Users/you/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
This shows the client version and the config files it used. Lines mentioning a Host block tell you which ones matched.
2. Connecting
debug1: Connecting to server [203.0.113.10] port 22.
debug1: Connection established.
Check that the address and port are the ones you expected. If you never reach Connection established, the problem is the network or the service, not your login:
ssh: connect to host 203.0.113.10 port 22: Connection refused
See connection refused, connection timed out and could not resolve hostname.
3. Identifying the keys, and meeting the server
debug1: identity file /Users/you/.ssh/id_ed25519 type 2
debug1: Local version string SSH-2.0-OpenSSH_10.3
debug1: Remote protocol version 2.0, remote software version OpenSSH_10.0p2 Debian-7+deb13u4
debug1: Authenticating to server:22 as 'user'
Check the user name in the last line. A wrong user is easy to miss and is enough to make a login fail. identity file ... type -1 means that file was not found, which is normal for key types you do not have.
4. Agreeing on algorithms
debug1: kex: algorithm: mlkem768x25519-sha256
debug1: kex: host key algorithm: ssh-ed25519
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
If there is no match, it stops here with an Unable to negotiate message. See no matching key exchange.
5. Checking the server's identity
debug1: Server host key: ssh-ed25519 SHA256:c+CTM4jkNvBP8UG87Uh12f2SwOsRapfKmGCO8Yv6tc4
debug1: Host 'server' is known and matches the ED25519 host key.
debug1: Found key in /Users/you/.ssh/known_hosts:1
If the key does not match, it stops here. See host key changed.
6. Logging in
Most problems are here. This is what a failure looks like:
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Will attempt key: /Users/you/.ssh/id_ed25519 ED25519 SHA256:5WGoVhFgmqkQ/7SmXA0cfMDG6u2weqiLGzzf+uY8hCg explicit
debug1: Offering public key: /Users/you/.ssh/id_ed25519 ED25519 SHA256:5WGoVhFgmqkQ/7SmXA0cfMDG6u2weqiLGzzf+uY8hCg explicit
debug1: Authentications that can continue: publickey,password
debug1: No more authentication methods to try.
user@server: Permission denied (publickey,password).
And this is success:
debug1: Offering public key: /Users/you/.ssh/id_ed25519 ED25519 SHA256:NxFS05Q+k1zf9LgrjGPL94UJfFS6B/89THkWACOEJgg explicit
debug1: Server accepts key: /Users/you/.ssh/id_ed25519 ED25519 SHA256:NxFS05Q+k1zf9LgrjGPL94UJfFS6B/89THkWACOEJgg explicit
Authenticated to server ([203.0.113.10]:22) using "publickey".
| What you see | What it means |
|---|---|
No Offering public key line | The client found no key to try. Check the path, or use -i. |
| A different key offered than you meant | Set IdentityFile and IdentitiesOnly yes for that host. |
Offering with no Server accepts key | The server did not accept that key. The reason is in its log. See below. |
Server accepts key, then a failure | The server likes the key, but the client could not sign, for example because of a wrong passphrase. |
Authentications that can continue lacks what you wanted | The server has turned that method off. |
See Permission denied (publickey) for the fixes.
7. After login
debug1: Entering interactive session.
debug1: Sending command: true
debug1: Exit status 0
If the login works and the session then closes at once, look at the shell, the startup files or a forced command on the server, not at SSH itself.
-v, -vv and -vvv
For one failed login, our test printed 49 lines with -v, 95 with -vv and 133 with -vvv.
-vvadds the full lists of algorithms each side offers, underlocal client KEXINIT proposalandpeer server KEXINIT proposal. Use it for algorithm problems.-vvvadds low-level detail such asdebug3: send packet: type 20. It rarely helps unless you are reporting a bug.
To keep the output in a file, or see only what matters:
ssh -v -E debug.log user@server
ssh -v user@server 2>&1 | grep -E 'Connecting|Offering|accepts|Authenticat|denied'
See the real settings: ssh -G
ssh -G server | grep -E '^(user|hostname|port|identityfile|proxyjump) '
This prints what the client would use after reading all of its config, and it does not connect. It settles most arguments about which Host block applies. With this config:
Host web*
User deploy
Port 2200
HostName 203.0.113.10
Host *
User other
Port 22
ssh -G web1 gives the following, because the first value found wins:
user deploy
hostname 203.0.113.10
port 2200
There is more in the guide on the ssh config file.
Test without a terminal: ssh -T
-T asks for no terminal. This helps to tell a problem with login apart from a problem with the session:
ssh -T user@server 'tty; echo TERM=$TERM'
not a tty
TERM=dumb
Services that give no shell, such as Git hosting, are normally tested this way: ssh -T git@github.com.
The server side
For security, the client only hears Permission denied. The reason goes in the server's log, so read that first if you have another way in. See how to check login attempts.
sshd -d on another port
This starts a second server that handles one connection, prints everything, and exits. Your normal sshd keeps running:
sudo /usr/sbin/sshd -d -p 2200
Then, from your machine:
ssh -p 2200 user@server
A firewall may need to allow that port. The full path is required: without it you get sshd requires execution with an absolute path. Here is the important part of the output when authorized_keys had the wrong mode:
debug1: userauth-request for user user service ssh-connection method publickey [preauth]
debug1: trying public key file /home/user/.ssh/authorized_keys
Authentication refused: bad ownership or modes for file /home/user/.ssh/authorized_keys
Failed publickey for user from 203.0.113.10 port 60932 ssh2: ED25519 SHA256:NxFS05Q+k1zf9LgrjGPL94UJfFS6B/89THkWACOEJgg
And when it works:
debug1: trying public key file /home/user/.ssh/authorized_keys
debug1: /home/user/.ssh/authorized_keys:1: matching key found: ED25519 SHA256:NxFS05Q+k1zf9LgrjGPL94UJfFS6B/89THkWACOEJgg
Accepted key ED25519 SHA256:NxFS05Q+k1zf9LgrjGPL94UJfFS6B/89THkWACOEJgg found at /home/user/.ssh/authorized_keys:1
Use -dd or -ddd for more. Stop it with Ctrl+C if nobody connects. If your connection never shows up in this output, something in front of the server, such as a firewall, is stopping it.
sshd -T: the settings in use
sudo sshd -T | grep -iE '^(port|passwordauthentication|pubkeyauthentication|authorizedkeysfile|permitrootlogin|maxauthtries) '
This reads the config files as the server does, including any included ones, and prints the results. It shows the settings as the files define them, so a server not yet reloaded may still be using older values. To see the effect of Match blocks, describe a connection:
sudo sshd -T -C user=user,host=client.example.com,addr=203.0.113.10 | grep -i passwordauthentication
Use sudo sshd -t to check the syntax only. It prints nothing if all is well.
Questions
Is it safe to share ssh -v output?
It does not contain your passwords or private keys, but it does show user names, host names, addresses, key paths and fingerprints. Read it through before you post it anywhere public.
Should I always use -vvv?
No. Start with -v. It answers most questions, and the extra levels add mostly protocol detail.