Systems troubleshooting guide10 min read

How to read TCP states in ss output

The state column becomes useful when you read it with the local and peer endpoints. Learn a repeatable `ss` workflow that distinguishes servers, live connections, closing sockets, and failed handshakes.

Reviewed by the Terminaster editorial team · Updated

What you will take away

  • LISTEN represents a server endpoint waiting for connections, not an established client session.
  • ESTAB means TCP completed its handshake; it does not prove the application-level request succeeded.
  • TIME-WAIT is normal TCP cleanup and usually belongs to the side that actively closed.
  • Endpoint columns, process data, timers, and state counts are more useful together than a state name alone.

Read state, local endpoint, and peer together

Start with numeric output so service-name lookup does not replace a port with a label. In `ss -tn`, State describes the TCP state, Local Address:Port is this host’s endpoint, and Peer Address:Port is the remote endpoint.

For a listener, the peer is typically a wildcard because no particular peer has connected to that socket. An accepted connection appears as a separate socket with both endpoints populated.

Build a readable TCP inventory

ss -ltn
ss -tn state established
ss -tan

# Ask ss for a compact state summary
ss -s

Separate LISTEN from ESTAB

LISTEN means a TCP socket is ready to receive new connection attempts. The Recv-Q and Send-Q fields have listener-specific meanings, including queue information; they are not simply unread and unsent application bytes.

ESTAB means the TCP handshake completed and the endpoints can exchange data. A TLS negotiation, HTTP request, database authentication, or application operation can still fail afterward.

  • One server process can own one listener and many established sockets.
  • A listener bound to 127.0.0.1 is host-local; a wildcard or interface bind has a different reach.
  • Use -p to request process details when permissions permit.
  • Filter by `sport` for a local server port and inspect both directions before assuming ownership.

Inspect a service on local port 443

ss -ltnp 'sport = :443'
ss -tnp state established 'sport = :443'

Interpret handshake and closing states as transitions

SYN-SENT means the local side initiated a connection and is waiting for the handshake to progress. SYN-RECV means a SYN arrived and the local TCP stack has replied while waiting for the final acknowledgement. Repeated or accumulating entries can be evidence of a path or load problem, but a single snapshot is not enough to establish one.

FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, LAST-ACK, CLOSING, and TIME-WAIT describe different parts of an orderly or simultaneous close. CLOSE-WAIT means the peer has closed and the local application has not yet closed its side. A persistently growing population may justify inspecting the owning application.

  • SYN-SENT: locally initiated handshake is incomplete.
  • SYN-RECV: incoming handshake is incomplete.
  • CLOSE-WAIT: the remote close was received; local application cleanup remains.
  • TIME-WAIT: TCP retains state temporarily to handle delayed segments safely.

Compare state counts over time

A busy service naturally creates many short-lived sockets. Capture a few samples during normal and failing periods, and relate them to request rate, errors, and process resource limits. Raw counts without traffic context are easy to misread.

If a state grows, filter to the relevant local port and inspect endpoints and timers. Add process details for states that still have an owning process, such as CLOSE-WAIT; TIME-WAIT entries normally no longer map to a userspace PID. Do not tune kernel TCP settings merely to hide a symptom before checking connection reuse, application close behavior, upstream health, and file-descriptor limits.

Inspect sockets and timers without changing state

ss -tanop
ss -tnp state close-wait
ss -tno state time-wait

# Repeat only as needed; avoid a tight polling loop
ss -s

Common questions

Frequently asked questions

Is a large number of TIME-WAIT sockets always a problem?

No. TIME-WAIT is part of correct TCP behavior and is common with many short connections. Judge it against workload, port pressure, error rates, and connection-reuse behavior before considering any tuning.

Why does ss show ESTAB when my HTTP request failed?

ESTAB only describes the TCP connection. TLS, authentication, HTTP status, application validation, and response processing happen above TCP and can fail independently.

What does an increasing CLOSE-WAIT count suggest?

It can indicate that peers closed connections while the local application has not closed its sockets. Confirm which process owns them and observe the trend before treating it as an application leak.

Keep learning

Sources and next steps