Inspect HTTP Keep-Alive Timeout Resets
Use packet capture to prove whether intermittent connection resets come from idle keep-alive timeouts on a proxy or the origin server.
Task
Capture traffic and compare idle intervals against keep-alive settings to attribute connection resets to the correct hop.
When to use this
A service sees sporadic ECONNRESET with no pattern; clients reuse pooled connections that may be closed by an intermediate proxy.
Prerequisites
- tcpdump or Wireshark available on the client host
- Knowledge of the proxy keep-alive timeout
- A reproducible burst of requests with idle pauses
Steps
1. Capture only the relevant traffic while forcing idle gaps.
sudo tcpdump -i eth0 -w keepalive.pcap 'tcp port 443 and host 203.0.113.10'
# drive requests with 60s idle gaps
sleep 65
curl -sv https://api.example.com/health 2>&1 | tail -5Expected output: The capture contains the FIN/RST sequence after the idle gap.
2. Inspect resets and who sends them in the capture.
tshark -r keepalive.pcap -Y 'tcp.flags.reset==1 or tcp.flags.fin==1' \
-T fields -e frame.time_relative -e ip.src -e tcp.flagsExpected output: The reset or FIN is attributed to a specific hop, revealing which side timed the connection out.
Troubleshooting
Problem
No resets appear in capture
Solution
Increase capture duration and idle far beyond the suspected timeout to force the event.
Problem
Resets come from both hops
Solution
Align the proxy keep-alive timeout below the origin so the pooled connection is not raced.
Limitations
- Needs packet capture privileges; production captures may be sensitive.
- Only attributes resets, it does not change timeouts by itself.
- TLS hides payloads but not TCP flags, which is enough here.
What this recipe does
Capture traffic and compare idle intervals against keep-alive settings to attribute connection resets to the correct hop.
A service sees sporadic ECONNRESET with no pattern; clients reuse pooled connections that may be closed by an intermediate proxy.
Prerequisites
- tcpdump or Wireshark available on the client host
- Knowledge of the proxy keep-alive timeout
- A reproducible burst of requests with idle pauses
Procedure
- Capture only the relevant traffic while forcing idle gaps.
sudo tcpdump -i eth0 -w keepalive.pcap 'tcp port 443 and host 203.0.113.10'
# drive requests with 60s idle gaps
sleep 65
curl -sv https://api.example.com/health 2>&1 | tail -5
Expected result: The capture contains the FIN/RST sequence after the idle gap.
- Inspect resets and who sends them in the capture.
tshark -r keepalive.pcap -Y 'tcp.flags.reset==1 or tcp.flags.fin==1' \
-T fields -e frame.time_relative -e ip.src -e tcp.flags
Expected result: The reset or FIN is attributed to a specific hop, revealing which side timed the connection out.
How to confirm it worked
Run the commands above and confirm every expected result in order. If a step does not produce the stated output, use the troubleshooting notes before continuing. A passing run shows tcpdump shows the FIN or RST attributed to one hop, matching that hop’s configured keep-alive timeout.
Troubleshooting
No resets appear in capture — Increase capture duration and idle far beyond the suspected timeout to force the event.
Resets come from both hops — Align the proxy keep-alive timeout below the origin so the pooled connection is not raced.
Limitations
- Needs packet capture privileges; production captures may be sensitive.
- Only attributes resets, it does not change timeouts by itself.
- TLS hides payloads but not TCP flags, which is enough here.