Runbook: Diagnosing Network Problems with Packet Captures
When 'the network is slow' isn't good enough to go on -- a repeatable process for capturing traffic with tcpdump and reading it in Wireshark to find the actual cause.
When to use this runbook
Reach for this when something more specific than "check if the service is up" has already failed to explain the problem -- intermittent connection failures, unexplained slowness between two specific hosts, or a symptom that smells like a network-layer issue rather than an application bug. Don't start here: check the obvious things first (is the service actually running, does ping work at all, is there an error in the application's own logs) -- packet capture is for when those don't explain what you're seeing.
Prerequisites
- Access to a machine positioned to see the relevant traffic (the affected client, the affected server, or a network tap/mirror port if you need to see traffic between two other hosts)
tcpdumpon the capturing machine; Wireshark on whatever machine you'll analyze the capture on (doesn't have to be the same machine)- Enough disk space for the capture -- unfiltered captures on a busy interface grow fast
Steps
Step 1: Define exactly what you're trying to see
Before capturing anything, be specific: which two hosts, which port/protocol, roughly what time window. A capture with no scope becomes a haystack.
Step 2: Capture with a filter, not everything
$ sudo tcpdump -i <interface> -w capture.pcap host <target-ip> and port <target-port>
Expected output: tcpdump runs silently, writing packets to capture.pcap, showing a running packet count. Reproduce the problem while this is running, then Ctrl+C to stop.
If you don't yet know the specific host/port (broader troubleshooting), a wider capture is fine but time-box it -- stop it as soon as you've captured the problem occurring, not indefinitely.
Step 3: Open the capture in Wireshark
$ wireshark capture.pcap
Or transfer the .pcap file to whatever machine has Wireshark installed -- capture and analysis don't need to happen on the same box.
Step 4: Check the TCP handshake first
Filter: tcp.flags.syn == 1
A healthy connection shows SYN → SYN, ACK → ACK in quick succession. If you see a SYN with no SYN, ACK response, the target isn't responding on that port at all (firewall, service down, or routing issue) -- a fundamentally different problem than a connection that completes the handshake and then has trouble.
Step 5: Look for the specific failure signatures below
Apply the relevant filter from the Diagnosis table and inspect what comes back.
Diagnosis
| Symptom | Wireshark filter | What you're looking for | Likely cause |
|---|---|---|---|
| Connection never establishes | tcp.flags.syn == 1 |
SYN sent, no SYN, ACK returned |
Firewall blocking the port, service not listening, or routing failure to the target |
| Connection resets unexpectedly | tcp.flags.reset == 1 |
RST packets, and which side sent them |
The receiving side actively refused/terminated -- often a firewall rule or the service itself rejecting the connection |
| Intermittent slowness, not total failure | tcp.analysis.retransmission |
Retransmitted segments | Packet loss somewhere on the path -- a flaky link, an overloaded switch, or a saturated interface |
| A specific hostname won't resolve | dns |
A DNS query with no matching response, or a NXDOMAIN/SERVFAIL reply |
DNS server unreachable or misconfigured -- see the recursive DNS guide elsewhere in this section if this points at your own resolver |
| High latency between request and response | Click a request packet, check Wireshark's Time since previous frame relative to its response |
A large gap between a request and its matching response | The far end is slow to respond (application-layer issue), not a network transport problem -- rules out the network as the cause |
Root cause and fix
Once the capture points at a specific layer (DNS, TCP handshake, packet loss, application response time), the fix is specific to that layer -- this runbook's job is narrowing down where the problem is, not fixing every possible cause. A SYN with no response, for example, sends you to check firewall rules (the OPNsense guide) or the target service's own status, not back into more packet captures.
Escalation
If the capture is inconclusive (traffic looks healthy on the segment you captured, but the problem persists), the issue may be on a different segment of the path than where you captured -- move the capture point closer to the other end (or capture simultaneously on both ends) rather than assuming the tool failed to show something.
Prevent recurrence
- If the root cause was packet loss on a specific link, that's a hardware/cabling investigation, not something this runbook fixes on its own
- If the root cause was a firewall rule blocking legitimate traffic, document the rule change once made so the next similar symptom doesn't require a full capture to diagnose again
- Keep this runbook's filters handy (a personal cheat sheet, or the CLI reference guide elsewhere in this section) -- the value here is in not re-deriving the right filter syntax under pressure during a real incident
Resources
Official documentation:
- tcpdump manual -- capture filter syntax, verified this session
- Wireshark documentation -- display filter syntax, verified this session
Source and releases:
Community:
Related DaemonPress projects:
- Recursive, Filtered DNS at Home -- relevant when the DNS diagnosis row applies
- VLAN Network Segmentation -- relevant when the problem is scoped to traffic crossing VLAN boundaries
Last verified: 2026-09-21, checked against official tcpdump and Wireshark documentation.