TCP TIME_WAIT socket exhaustion — ephemeral port exhaustion
Cannot assign requested address errors when connecting out
Focused incident mode — strips away everything but this runbook.
Symptoms
- Cannot assign requested address errors when connecting out
- ss -tan shows thousands of TIME_WAIT sockets
- Short-lived HTTP connections exhaust the ephemeral port range
TIME_WAIT is a protocol safety mechanism — it prevents old packets from corrupting new connections. Tweaking it (tw_reuse) is safe; disabling it entirely is not.
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
TIME_WAIT socket count
ss -tan state time-wait | wc -lEphemeral port range
cat /proc/sys/net/ipv4/ip_local_port_range
Diagnostic flow
Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.
Guided decision tree is ready.
Steps with commands, expected output, and pass/fail branches.
Ranked root causes
Evidence checklist
- Application opens a new TCP connection per HTTP request
- TIME_WAIT count grows under load
Confirm before fixing
ss -tan state time-wait | wc -lConfirm high TIME_WAIT count
Fix
sysctl -w net.ipv4.tcp_tw_reuse=1 && sysctl -w net.ipv4.tcp_fin_timeout=15Enable TIME_WAIT reuse and reduce FIN timeout
Resolution runbook
Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.
ss -tan state time-wait | wc -lCount TIME_WAIT sockets
cat /proc/sys/net/ipv4/ip_local_port_rangeCheck the ephemeral port range
sysctl -w net.ipv4.tcp_tw_reuse=1Enable TIME_WAIT socket reuse
sysctl -w net.ipv4.ip_local_port_range='1024 65535'Expand the available port range
Prevention
- Use HTTP connection keep-alive or connection pooling to reduce connection churn.
- Set net.ipv4.tcp_tw_reuse=1 on servers with high outbound connection rates.
- Expand ip_local_port_range for high-churn proxy servers.
- Monitor TIME_WAIT count via node_exporter and alert on sustained high values.
Related runbooks
Same stack, same failure family — worth a skim.
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.