Linux / Bash

Linux SSH Connection Hangs on "Authenticating" or Drops Frequently

An SSH connection that hangs specifically during authentication, or that drops unexpectedly after connecting successfully, usually traces back to one of a small set of well-understood causes — a slow reverse DNS lookup on the server side, missing keepalive configuration, or a network path with an MTU mismatch causing larger packets to silently fail.

The Problem

Connecting via SSH either hangs for a long time at a specific point before eventually connecting (or timing out entirely), or connects successfully but drops unexpectedly after some period of inactivity:

debug1: Authenticating to server:22 as 'user'
# hangs here for 10-30+ seconds before proceeding, or times out entirely
Write failed: Broken pipe
client_loop: send disconnect: Broken pipe

Why It Happens

Several distinct, common causes produce these symptoms, and they require different fixes depending on which one applies:

  • The SSH server is configured to perform a reverse DNS lookup on connecting clients as part of its logging/authentication process, and if that DNS lookup is slow or fails to resolve, the entire connection stalls waiting for it to complete or time out
  • No keepalive mechanism is configured on either the client or server side, so an idle connection through certain network equipment (routers, firewalls, NAT gateways) gets silently dropped after a period of inactivity, without either side being explicitly notified
  • An MTU (Maximum Transmission Unit) mismatch somewhere along the network path causes larger packets to be silently dropped rather than properly fragmented, which can manifest as a connection that establishes but then hangs or drops once actual data transfer begins
  • Server-side resource exhaustion (too many concurrent connections, high CPU load) delaying the server's ability to respond to new connection attempts promptly

The Fix

For a hang specifically during authentication, disable the SSH server's reverse DNS lookup, which is a very common and easy fix for exactly this symptom:

# /etc/ssh/sshd_config
UseDNS no

Restart the SSH service after this change for it to take effect:

sudo systemctl restart sshd

For connections dropping after periods of inactivity, configure keepalive settings on the client side, in your SSH config file:

# ~/.ssh/config
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

This sends a small keepalive packet every 60 seconds during idle periods, and if 3 consecutive keepalives go unanswered, the client proactively disconnects rather than sitting in an ambiguous, silently-dropped state — importantly, sending these periodic packets also prevents many NAT gateways and firewalls from treating the connection as idle and quietly dropping it in the first place.

For a matching server-side setting, which helps in the reverse direction (server detecting a genuinely dead client connection rather than continuing to hold resources for it):

# /etc/ssh/sshd_config
ClientAliveInterval 60
ClientAliveCountMax 3

If you suspect an MTU mismatch (more common over VPNs, certain cloud network configurations, or specific ISP setups), test with a smaller MTU explicitly to see if it resolves the issue, which helps confirm the diagnosis even before implementing a permanent fix:

ssh -o "IPQoS=throughput" user@host

For a more direct MTU diagnosis, test with progressively smaller packet sizes using ping's don't-fragment flag to find the actual maximum size that successfully passes through the network path without being silently dropped:

ping -M do -s 1472 destination-host

Reduce the size incrementally until packets succeed, which reveals the actual usable MTU along that specific path — a persistent mismatch may require adjusting your network interface's configured MTU, or investigating with your network provider if the issue is happening at a hop outside your direct control.

Still Not Working?

If none of the above resolves the issue, run SSH in verbose debug mode to get much more granular insight into exactly where in the connection process things are stalling or failing:

ssh -vvv user@host

The triple-verbose output shows every step of the connection and authentication process with timestamps, making it possible to pinpoint precisely which phase is slow or failing, rather than relying on the general symptom category alone to guess at the underlying cause.