Skip to content
Community

EXPLORE TOPICS

Editorial approach

New to CoreTrailKit?

Observe your services. Keep the evidence close.

CoreTrailKit
Back to articles
GUIDE/ SSH

SSH broken pipe: test idle keepalives and limits

An SSH session works while you type but disappears after an idle period. A broken pipe is the final symptom, not a complete explanation of whether the server, network, or local computer stopped the connection.

By CoreTrailKit3 min read

01

Collect the timing and scope

Note whether disconnects follow a consistent idle duration, a laptop sleep event, a network switch, or server maintenance. Compare with a bounded test on another authorized host or network when possible. A repeatable pattern narrows the investigation but does not identify the cause by itself.

Review the client’s effective keepalive settings and the server logs around the disconnect. If the server intentionally ends idle sessions or a shell timeout is configured, adding client probes may not change that policy.

sh · EXAMPLE
ssh -G app-server
ssh -v app-server

02

Apply keepalives to the affected host

ServerAliveInterval asks the client to send an encrypted protocol-level check when it has not received data from the server. ServerAliveCountMax bounds unanswered checks before disconnection. These differ from relying solely on TCP keepalive behavior.

Start with one host entry and choose values that fit the network and server policy. Place the specific rule before broad defaults where needed, then inspect it with ssh -G. Avoid changing every destination just because one path has an idle problem.

sshconfig · EXAMPLE
Host app-server
  HostName server.example.com
  ServerAliveInterval 30
  ServerAliveCountMax 3

03

Test healthy idleness and an unavailable peer separately

Our healthy lab connection remained open during a short idle command and returned its final marker. In a separate run, we paused only the disposable server after authentication. With one-second checks and a count of two, the client detected the unresponsive peer and exited.

That test establishes failure detection in a controlled case. It does not prove that a thirty-second interval will overcome a particular router’s timeout, or that all client disconnects share the same cause. Sleep and link loss can still interrupt the transport.

sh · EXAMPLE
# Example of a short benign idle check on an authorized server:
ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=3 \
  app-server 'sleep 120; printf "idle check completed\n"'

04

Do not confuse detection with recovery

A new SSH connection is a new transport. The keepalive options do not reattach its terminal, replay a command safely, or establish whether a partially completed operation succeeded. After a disconnect, check the remote result before retrying a state-changing command.

If long-running work must survive terminal loss, use a workflow designed for that requirement, such as an approved terminal multiplexer or service manager. Configure that deliberately rather than treating a longer timeout as job supervision.

05

Verify the original use case after the change

Repeat the ordinary idle pattern that used to fail, and compare the timing and logs. If disconnects continue at exactly a server-enforced deadline, investigate that policy with its owner. If they track laptop sleep or network changes, keepalive tuning may be the wrong lever.

Keep only the setting that the evidence supports. A faster error is useful when a connection is dead, but it is a different outcome from a connection that now stays usable. Record which outcome you actually observed.

Know the limits

Tested with OpenSSH 9.2p1 against a healthy idle server and a deliberately paused disposable server. We did not simulate a real NAT idle timer. The short one-second lab interval is for reproduction; the example configuration uses a less aggressive interval.

Sources & further reading

A technical publication by CoreTrailKit.

Browse all articles

CONTINUE EXPLORING