TCP RST and Connection Reset PCAP Analysis: Who Closed the Connection and Why
How to analyze TCP RST, connection reset by peer, reset after SYN, reset during TLS, firewall resets, application closes, and packet capture evidence.
Connection reset by peer tells an HTTP client, database, or TLS stack that a TCP RST arrived; it does not prove which system originated it. Inspect direction, sequence and acknowledgment validity, TTL/IP-ID patterns, preceding payload, idle duration, and whether the reset followed SYN or a TLS record to narrow the source to an endpoint or an in-path firewall/load balancer. A single capture can identify the apparent sender and exact trigger visible there, but spoofed or injected resets require another vantage point for certainty.
A TCP RST is explicit. It says "abort this connection." The hard part is attribution.
PCAP Surgery is useful because reset investigations need a clean, focused trace with direction, timestamps, sequence numbers, and enough packets before the reset.
Common reset patterns
RST can happen:
- Immediately after SYN.
- After SYN-ACK.
- After ClientHello.
- After HTTP request.
- During idle timeout.
- After invalid protocol data.
- When an application closes a socket with unread data.
- When a firewall rejects a policy.
- When a load balancer has no healthy backend.
- When a server process crashes or refuses state.
The timing tells you where to look.
Who sent the RST
First identify source IP, source port, destination IP, and destination port of the reset packet. If the server IP sends RST, the server side or something impersonating that side ended it. If the client IP sends RST, the client side ended it. If TTL, MAC, or path behavior suggests a middlebox, the reset may be injected.
Do not rely only on application wording. "Reset by peer" may be reported by the side that received the RST.
Reset after SYN
RST after SYN often means the port is closed or policy rejects the connection. If SYN receives RST immediately, the application never reached TLS or HTTP.
Look for:
- SYN -> RST,ACK
- No ServerHello
- No application data
- Consistent behavior across attempts
This is not a certificate failure or HTTP error; it is a TCP reachability/service state failure.
Reset during TLS
RST after ClientHello can be caused by wrong port, unsupported TLS, SNI mismatch, middlebox policy, or server rejection. Preserve DNS and ClientHello metadata so you can see hostname, ALPN, TLS versions, and timing.
If the reset arrives after a TLS alert, the alert is more informative than the reset. If there is no alert, the reset may be lower-level or policy-driven.
Reset after request
RST after HTTP request, database query, or protocol command often means the application understood enough to reject or crash on the request. It can also mean a proxy closed because upstream was unavailable.
Correlate:
- Last application bytes sent.
- Server response or lack of response.
- Idle time before reset.
- Backend/load-balancer logs.
- Whether reset happens only for certain request sizes.
Checklist
Use this workflow:
- Identify the first RST in the conversation.
- Identify who sent it.
- Inspect what happened immediately before it.
- Check whether TCP handshake completed.
- Check whether TLS began or completed.
- Check whether application data was sent.
- Check for idle timeout timing.
- Compare TTL/MAC/path clues for middlebox injection.
- Preserve DNS, TCP, TLS, and application bytes around the reset.
- Use server/load-balancer logs to confirm attribution.
Final diagnosis
TCP RST is a connection abort, but the reason depends on timing and sender. A pcap can distinguish closed port, firewall reject, TLS rejection, application close, idle timeout, load balancer failure, and middlebox reset.
PCAP Surgery helps preserve the packet sequence that answers the most important question: who reset the connection, and what happened just before it?
Reset-stage decision table
Classify the first reset by connection stage before searching for a cause. Later resets may be cleanup after the meaningful failure.
| First RST boundary | Strong first lead | Evidence needed next |
|---|---|---|
| RST,ACK immediately after SYN | Closed port, listener absence, reject policy | Service bind state and firewall logs |
| Client RST after SYN-ACK | Client abandoned or state mismatch | Client socket/runtime logs |
| RST after ClientHello | TLS listener, SNI/version policy, middlebox | TLS endpoint and proxy logs |
| RST after complete request | App/proxy rejection, crash, unread data | Correlation ID and server spans |
| RST after fixed idle period | Firewall/LB/application idle timeout | Configured timers on every TCP leg |
| RST during large transfer | App abort, resource limit, MTU/loss side effect | Sequence, window, size, host logs |
An RST with an in-window sequence number is more likely to be accepted by the endpoint. Compare sequence and acknowledgment values with the preceding flow. A reset that does not match connection state may be ignored, duplicated, delayed, or injected against stale state.
Attribute endpoint versus middlebox carefully
Source IP alone is insufficient because a firewall, proxy, or load balancer can emit a packet using an endpoint-facing address. Compare TTL/hop limit with prior packets from the apparent sender, source MAC at the capture point, IP ID behavior where relevant, TCP timestamp option presence, and arrival at multiple sensors.
| Clue | Supports | Limitation |
|---|---|---|
| Same TTL and MAC as prior server packets | Server-side origin at this segment | Proxy may share L2/path identity |
| RST appears only downstream of firewall | Injection at or after that boundary | Requires synchronized captures |
| Endpoint log records abort at same time | Endpoint application/kernel origin | Clock and flow correlation must match |
| Reset TTL differs consistently | In-path origin lead | Routes and initial TTL can vary |
| Server capture lacks RST, client sees it | In-path injection or capture gap | Verify server capture completeness |
Use bounded language: “RST appeared with the server address at the client-side sensor” is a packet fact. “The server application sent it” requires corroboration.
Why applications generate resets
An application can close a socket abortively, crash, exceed a request/body limit, reject a protocol spoken on the wrong port, or close while unread data remains. The kernel may answer a packet for a nonexistent socket with RST. A reverse proxy can translate upstream connection failure into downstream reset behavior.
Correlate the final acknowledged request bytes with server logs. If the request was never fully delivered, application parsing may not have begun. If a complete request precedes the reset, retain request size, route or command where visible, and correlation ID. Encrypted traffic still permits a bounded direction/size/timing statement.
Is connection reset by peer always the peer application?
No. It means the local stack received a reset associated with the connection. The origin may be the peer kernel/application, a terminating proxy, or an in-path device. Inspect topology and capture points.
Is an RST after idle time a firewall timeout?
It may be, but application servers and load balancers also enforce idle, keepalive, request, and connection-age timers. Measure the last bidirectional activity to reset across repeated flows and compare every TCP leg’s configured timer.
Can packet loss create an RST?
Loss itself usually triggers retransmission, not reset. An application may abort after its own timeout, or stale state can cause a later packet to reach a device with no connection entry and receive RST. Preserve the loss/retry sequence and timeout boundary.
Multi-leg proxy diagnosis
For a proxy, label client→proxy and proxy→backend as separate TCP flows. A backend RST can cause the proxy to send an HTTP error, FIN, or a different RST to the client. Do not copy sequence timing from one leg to the other. Correlate using proxy request IDs and log timestamps.
| Backend event | Possible client-side result |
|---|---|
| Backend connect RST | 502/503, retry, or client reset |
| Backend idle close | New backend connection or downstream error |
| Backend request reset | Proxy error response or stream reset |
| Proxy policy rejection | Client-side RST without backend flow |
Regression test after a reset fix
Reproduce the same connection stage, request, size, idle interval, client version, and proxy route. Capture one healthy and one formerly failing case. Require the expected protocol response or graceful FIN sequence, absence of the original first RST boundary, and matching application success.
Do not simply increase timeouts. A longer timer can hide a leaked or stalled connection. Confirm the owner-specific behavior: listener remains available, TLS policy accepts the intended ClientHello, application handles the request, pool health is restored, or firewall state persists as designed.
Actionable evidence handoff
Include flow tuple, capture point, first RST time/direction, sequence/ack validity, connection stage, final payload boundary, idle duration, TTL/MAC comparison, retransmissions/window state, proxy legs, and matching host/log interval. State the exact unproven attribution.
Preserve DNS and handshake when identity matters, several packets before the reset, the RST, any retries, and subsequent new connection. Use capture scope help and the packet preparation workflow before sharing.
If the reset occurs during TLS, continue with the TLS handshake failure guide. If it follows an idle boundary, compare TCP keepalive and firewall timeout evidence.
Compare repeated resets instead of one outlier
Group flows by the stage and interval before the first RST. A fixed reset age across many otherwise healthy connections suggests lifecycle policy. A reset tied to one request route or payload size suggests application/proxy handling. Random resets with retransmission bursts require transport and capture-quality review.
| Grouping dimension | What a pattern can reveal |
|---|---|
| Time since connection open | Max-age or idle policy |
| Time since last payload | Idle/keepalive boundary |
| Request route or command | Application-specific rejection |
| Payload size | Limit, parser, or MTU-related path |
| Backend node | Unhealthy instance or pool member |
| Client/runtime version | Socket/TLS behavior difference |
Preserve exceptions as well as the dominant pattern. One graceful close among resets can show the expected lifecycle; one reset on an otherwise healthy node can identify an input-specific trigger.
Can a stale packet legitimately receive RST?
Yes. Delayed packets from an old incarnation of the same tuple can arrive after state has closed, or NAT may reuse ports. Sequence validity, TCP timestamps, connection start, and TIME_WAIT behavior help distinguish stale traffic from an active-flow abort.
Why does closing with unread data matter?
On some stacks, closing a socket while receive data remains unread can produce abortive behavior. Correlate the peer’s final sent bytes, ACK progress, application read/close logs, and whether a graceful shutdown call changes the packet sequence.
Minimum regression assertions
Automate what can be checked: handshake completes, expected application response arrives, no RST occurs before that response, and teardown matches the intended FIN policy. For timeout paths, assert the configured interval within tolerance and identify which side initiates closure.
The final incident owner should be specific: listener/service owner for SYN resets, TLS policy owner for ClientHello resets, application/proxy owner after complete request, lifecycle/network owner for repeated idle-age resets, and transport owner only when sequence evidence shows loss or path inconsistency.
Always retain the immutable source capture.
<!-- multilingual-related-reading:start -->Related guides
Continue with the same-language pages below. They cover adjacent stages without changing the canonical owner of this topic:
<!-- multilingual-related-reading:end -->