When connecting to an SSH server, the connection hangs and then fails:

bash
$ ssh user@server.example.com
banner exchange: Connection to 192.168.1.100 port 22: Connection timed out

Or you might see:

bash
ssh_exchange_identification: read: Connection timed out

This error occurs during the initial SSH protocol handshake. The server should immediately send a banner like SSH-2.0-OpenSSH_8.9p1, but it's not responding in time.

Understand the Banner Exchange

When you connect, the server must immediately send its protocol identification:

bash
SSH-2.0-OpenSSH_8.9p1 Ubuntu-3

This happens before any authentication. If the server takes too long, the client times out.

Check Network Connectivity

First, verify basic connectivity:

bash
ping -c 3 server.example.com

If ping fails or is very slow, you have a network issue.

Test if the port is reachable:

bash
nc -zv server.example.com 22 -w 5

If this times out, the server might not be reachable or a firewall is blocking.

Test Banner Response

Use telnet or nc to see if the server sends its banner:

bash
nc server.example.com 22

Or:

bash
timeout 5 telnet server.example.com 22

A healthy server responds immediately:

bash
SSH-2.0-OpenSSH_8.9p1

If there's a long delay before this appears, the server has performance issues.

Check Server-Side DNS Resolution

SSHD might be trying to resolve your client's hostname. On the server, disable DNS lookups:

bash
sudo grep UseDNS /etc/ssh/sshd_config

If set to yes or missing (defaults to yes):

bash
sudo sed -i 's/^UseDNS.*/UseDNS no/' /etc/ssh/sshd_config

Or add it:

bash
echo "UseDNS no" | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart sshd

This prevents the server from doing reverse DNS lookup on your IP, which can cause delays if DNS is slow.

Check Server GSSAPI

GSSAPI authentication can cause banner delays:

bash
sudo grep GSSAPIAuthentication /etc/ssh/sshd_config

If enabled and you're not using GSSAPI:

bash
sudo sed -i 's/^GSSAPIAuthentication.*/GSSAPIAuthentication no/' /etc/ssh/sshd_config
sudo systemctl restart sshd

Also check:

bash
sudo grep GSSAPICleanupCredentials /etc/ssh/sshd_config

Increase Client Timeout

If the server is legitimately slow, increase your client timeout:

bash
ssh -o ConnectTimeout=30 user@server.example.com

In ~/.ssh/config:

bash
Host slow-server.example.com
    ConnectTimeout 30

Default timeout is typically around 10 seconds.

Check Server Load

On the server, check if it's overloaded:

bash
top -bn1 | head -20

Or:

bash
uptime

High load can delay SSHD's response to new connections.

Check SSHD process count:

bash
ps aux | grep sshd | wc -l

Too many SSHD processes might indicate MaxStartups throttling.

Check MaxStartups Configuration

SSHD throttles connections when many are arriving:

bash
sudo grep MaxStartups /etc/ssh/sshd_config

Default is 10:30:100. If connections exceed 10, new ones are dropped with increasing probability.

Increase it:

bash
echo "MaxStartups 50:30:100" | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart sshd

Check Server Firewall

Server-side firewalls can rate-limit connections:

bash
sudo iptables -L INPUT -v -n

Look for rules with recent module or rate limiting:

bash
DROP       tcp  --  anywhere             anywhere            tcp dpt:ssh recent: UPDATE seconds: 60 hit_count: 4 name: ssh side: source

Temporarily disable to test:

bash
sudo iptables -F

For firewalld:

bash
sudo firewall-cmd --list-all

Check MTU Issues

Large packets might be dropped, causing delays during key exchange:

bash
# On client
ip link show eth0 | grep mtu

Test with smaller MTU:

bash
ssh -o "MTU=1200" user@server.example.com

Check for Proxy or Load Balancer

If there's a proxy between you and the server, it might be slow:

bash
# Test direct connection if possible
ssh user@192.168.1.100  # Direct IP, bypass DNS

Load balancers can also cause delays if misconfigured for SSH.

Check SSHD Logs

On the server, watch SSHD activity:

bash
sudo journalctl -u sshd -f

Connect and look for:

bash
Apr  3 10:15:22 server sshd[12345]: Connection from 192.168.1.50 port 22 on 192.168.1.100 port 22
Apr  3 10:15:25 server sshd[12345]: Did not receive identification string from 192.168.1.50 port 22

The "Did not receive identification string" means the client didn't respond quickly enough.

Check Client-Side Issues

Your client might have problems. Check SSH client config:

bash
cat ~/.ssh/config | grep -i timeout

Check for slow DNS on your side:

bash
time nslookup server.example.com

If DNS takes seconds, add to /etc/hosts:

bash
echo "192.168.1.100 server.example.com" | sudo tee -a /etc/hosts

Use IP Instead of Hostname

Bypass DNS entirely:

bash
ssh user@192.168.1.100

Check SSHD Banner Configuration

If a custom banner is configured:

bash
sudo grep Banner /etc/ssh/sshd_config

If Banner points to a slow filesystem or large file, it could cause delays. Remove it:

bash
sudo sed -i 's/^Banner/#Banner/' /etc/ssh/sshd_config
sudo systemctl restart sshd

Check TCP Wrappers

TCP wrappers can cause delays during connection:

bash
cat /etc/hosts.allow
cat /etc/hosts.deny

Complex rules or DNS checks in these files can slow the initial handshake.

Test from Different Network

Connect from a different location to rule out your network:

bash
ssh user@server.example.com

If it works from elsewhere, your network is the issue.

Resolution Checklist

  1. 1.Test network connectivity: ping and nc -zv
  2. 2.Check banner response: nc server 22
  3. 3.Disable DNS lookups: UseDNS no
  4. 4.Disable GSSAPI: GSSAPIAuthentication no
  5. 5.Increase client timeout: ConnectTimeout 30
  6. 6.Check server load and MaxStartups
  7. 7.Check firewall rate limiting
  8. 8.Use IP instead of hostname
  9. 9.Check MTU if network is unstable

Banner exchange timeouts are usually caused by slow DNS resolution or overloaded servers. Start by testing the raw banner response and disabling DNS lookups on the server.