Packet Capture on Windows in Practice — Choosing Among pktmon, netsh trace, and Wireshark

· · Windows, Packet Capture, pktmon, netsh, Wireshark, Network, Troubleshooting, TCP/IP

“The business app’s server communication fails a few times a month. The app log only says ‘timeout’. There is no matching error in the server-side log at that time. We do not know how to reproduce it” — in bug-investigation consultations, this shape comes up constantly.

An app log only keeps what the app “decided to write”. You can see that the result was a timeout, but whether the connect request (SYN) got no reply, whether the connection was established and then the server went silent, whether it was torn down with a RST, or whether the packet even reached the destination, lives one layer below the log — in the packets that actually went over the wire. If Process Monitor is the way to look one layer down at file and registry access, packet capture is the way to look one layer down at the conversation.

The packets one layer below the app logAn app log only keeps what the app decided to write; whether SYN got no reply, the peer went silent after connect, a RST tore the connection down, or the packet even arrived lives only in the packets that actually went over the wirelook one layer downApp logOnly what the app decided to write remainsThe result is a one-word timeoutPackets that actually went over the wireNo reply to SYN?Silent after connect?Torn down with RST?Did it reach the destination?

Figure 1: The log keeps only the result; the breakdown of a timeout lives only in the packets one layer down.

The typical place people get stuck is the constraint “we cannot install Wireshark on the customer’s server”. Sites where change control or a security policy will not approve extra software for an investigation are not rare. Windows, however, already ships two packet-capture tools: pktmon and netsh trace. Capture with the inbox OS tools, take the resulting file back to your own PC, and read it in Wireshark — with that split, you can still see the packets on a site that forbids installs.

This article is aimed at IT staff at small and midsize companies and at Windows app developers. It organizes how to choose among pktmon, netsh trace, and Wireshark, and the practical procedure for each. Loopback-traffic traps, deciding whether to capture on the client or the server, how to live with TLS hiding the payload, and correlating the capture with the app log are all covered from primary sources current as of August 2026.

1. The Bottom Line First

  • “Capture with the inbox tool, read with Wireshark” is the basic split on site. Even if you cannot install software on the customer server, pktmon and netsh trace are built into Windows. Convert the captured log to pcapng and analyze it in Wireshark on your own machine.12
  • pktmon is the packet-capture tool built into Windows 10 / Windows Server 2019 and later. You use it in four steps — register a filter, start, stop, convert — and its distinctive strength is that you can see which network-stack component discarded the packet (the drop reason).34
  • netsh trace is the older inbox tool; it can enable a bundle of ETW providers as a “scenario”. In addition to packets it keeps events from inside Windows components, and with persistent=yes the capture can survive a reboot.56
  • Both tools write ETL, which Wireshark cannot open as-is. Convert to pcapng with pktmon etl2pcap for pktmon, and with Microsoft’s open-source etl2pcapng for netsh trace.12
  • Microsoft itself points to “pktmon first, then netsh trace if that is not enough, and Wireshark for protocol analysis”. The split in this article follows that official recommendation.7
  • By default pktmon records only the first 128 bytes of each packet. If you intend to read the payload in Wireshark, do not forget --pkt-size 0 (record the whole packet) when you start.8
  • Traffic to localhost does not appear in a normal capture. It never goes through a NIC. Use Npcap’s loopback adapter in Wireshark, or pktmon’s in-stack capture with the inbox tools.9
  • Even when TLS hides the payload, you can still learn a lot. Connect establishment, whether the TLS handshake succeeded, RST, and which side went silent are visible even when encrypted. Decryption via SSLKEYLOGFILE is a development-environment-only technique.10
  • A capture contains the communication itself. Assume it can include credentials and personal information, and build minimum-necessary capture and pre-handoff narrowing into the procedure.

2. The Three Capture Tools and How to Choose Among Them

First, a single table of the three tools’ roles.

  pktmon netsh trace Wireshark
How you get it Built into Windows 10 / Windows Server 2019 and later3 Built into Windows for a long time (usable on OSes from before pktmon) Separate install required
Main role Packet capture, drop detection, counters Packet capture + ETW events from Windows components Analysis of captured data (the real destination)
Output format ETL (convert to pcapng with etl2pcap)1 ETL+.cab (convert to pcapng with etl2pcapng)62 pcapng
Distinctive strength Drop location and reason inside the stack4 Bundling providers by scenario, capture across reboots5 Display filters, TCP analysis, statistics, GUI
Rights Administrator Administrator Administrator-equivalent to capture (not needed for analysis only)

In one sentence, pktmon and netsh trace are the “capture” tools, and Wireshark is the “read” tool. Wireshark can capture too, but you cannot use that where you cannot install it. Conversely, you can convert inbox-tool ETL to text and read it, but staring at it with no display filter and no TCP analysis is misery. “Capture on site with the inbox tool, convert to pcapng, and read in Wireshark on your own machine” is the shortest path on a constrained site.

Capture with the inbox tool, read with WiresharkOn site you capture ETL with pktmon or netsh trace, convert each to pcapng with its conversion tool, and analyze in Wireshark on your own machinepktmon etl2pcapetl2pcapngpktmon (inbox)ETL filenetsh trace (inbox)ETL+.cabpcapngAnalyze in Wireshark on your machine

Figure 2: On site you capture ETL with the inbox tools, convert to pcapng, and read it in Wireshark on your own machine.

Microsoft’s packet-loss investigation guide has the same shape: capture and isolate the cause with pktmon first, then move on to component-level traces such as netsh trace start scenario=InternetClient if that is not enough, and analyze protocol behaviour in Wireshark.7

As a prerequisite for reading what a packet actually shows, it also helps to have a picture of the stacked layers — Ethernet, IP, TCP, application data. The layer anatomy is illustrated in “Getting a Real Feel for the OSI Model”.

3. pktmon in Practice — Filter, Start, Stop, Convert

pktmon’s basic flow is four steps. Run them in an elevated terminal.

:: 1. Register a filter first to narrow the target (TCP 8443 on server 192.168.10.20)
pktmon filter add App8443 -i 192.168.10.20 -t tcp -p 8443
pktmon filter list

:: 2. Start the capture. Record whole packets, overwrite in a 1GB ring buffer
pktmon start --capture --pkt-size 0 --file-name C:\temp\app-timeout.etl --file-size 1024 --log-mode circular

:: 3. Reproduce the incident. While you wait you can check volume and drops with counters
pktmon counters --drop-reason

:: 4. Stop, then convert to pcapng for Wireshark
pktmon stop
pktmon etl2pcap C:\temp\app-timeout.etl --out C:\temp\app-timeout.pcapng

:: 5. Clean up the registered filter (filters stay until you remove them explicitly).
::    Note: filter remove cannot take a name; it deletes "all" registered filters.
::    On a machine that may still have another investigation's filters, check with pktmon filter list first
pktmon filter remove
Basic pktmon procedureNarrow the target with a filter, start the capture, reproduce the incident, stop, convert to pcapng with etl2pcap, and finally remove the registered filter1. Narrow the target with filter add2. Start capture with start --capture3. Reproduce the incidentCheck volume and drops with counters4. StopConvert to pcapng with etl2pcap5. Clean up with filter remove

Figure 3: pktmon starts with filter registration, then capture, stop, and convert, and you remove the filter explicitly at the end.

Points to keep in mind:

  • Register filters before you start the capture. Microsoft’s documentation also strongly recommends applying a filter before you start, because capturing all traffic is too noisy. Filters can specify IP address, port, MAC address, protocol, VLAN ID, and so on, and you can register up to 32. Multiple filters are an OR: a packet is recorded if it matches any of them.3
  • A pktmon filter does not distinguish source from destination. -i 192.168.10.20 means “packets where this address is the source or the destination”. Narrow the direction later with a Wireshark display filter after conversion.3
  • The default packet size is 128 bytes. That is enough for header analysis, but if you want application data as well, record the whole packet with --pkt-size 0.8
  • The log defaults to circular (ring-buffer) mode, default size 512MB. You can change the cap with --file-size, and --log-mode real-time prints to the screen in real time and does not create a log file. Confirm first in real-time mode that you can actually see the traffic you care about, then set the production capture, and you avoid an empty take.8
How pktmon filters take effectMultiple registered filters record on an OR match, the specified address does not distinguish source from destination, and direction is narrowed later with a Wireshark display filter after conversionFilter 1Record if any matchesFilter 2Filter 3 (up to 32)Recorded in the capture log (OR)Source and destination are not distinguishedNarrow direction in Wireshark after conversion

Figure 4: Multiple filters work as OR, and whether a host is source or destination is narrowed in Wireshark after conversion.

3.1. What Only pktmon Can Do — Seeing Where a Packet Was Dropped

pktmon’s distinctive value versus Wireshark is that it captures a packet at multiple points inside the network stack, not at a single NIC, and can report where and why it was discarded (dropped). Because you can see which component a packet reached and where it disappeared, drop reasons such as “MTU mismatch” or “VLAN filter” get you to the cause without a brute-force search.4

pktmon captures at multiple points inside the stackpktmon captures a packet at multiple points inside the network stack rather than at a single NIC, so it can report with a reason which component the packet reached and where it was discardedPacketCaptured at point 1Captured at point 2Discarded at point 3Reports drop location and reasone.g. MTU mismatch or VLAN filter

Figure 5: Capturing at multiple points inside the stack tells you how far a packet got and where it was dropped, with a reason.

  • pktmon list shows the network components that can be monitored (NICs, protocol stacks, filter drivers, and so on) and their IDs.
  • pktmon counters --drop-reason lists per-component pass/drop counters and the most recent drop reason. Convenient as a first cut before you analyze the log.11
  • Convert to text with pktmon etl2txt and discarded packets are emitted with drop and a dropReason.3

The suspicion that “something in the OS is dropping this before it reaches the app” cannot be settled by staring at Wireshark alone. This capability helps, for example, when isolating a case that the firewall is dropping because an inbound rule is missing (“The Windows Firewall and Business Applications”).

One caveat. pktmon records the same packet at multiple points in the stack, so converting as-is to pcapng can make the same packet appear more than once. pcapng does not carry “which component captured this”, so if you are reading in Wireshark the standard move is to convert with --component-id to pick one point (or put drops alone in a separate file with --drop-only).1

Why the same packet can appear twice after pcapng conversionpktmon records the same packet at multiple points in the stack, pcapng does not keep which component captured it so duplicates can appear, and the standard move is to convert after narrowing the point with component-id or putting drops alone in a drop-only fileSame packet recorded at multiple pointsConvert to pcapng as-isCapture-point information is not carried overThe same packet appears more than onceNarrow the point with --component-idSeparate file with --drop-only

Figure 6: Capture-point information is not carried into pcapng, so the standard move is to narrow the point before converting.

4. netsh trace in Practice — Scenarios, ETL, and Captures That Survive a Reboot

netsh trace is the tracing mechanism that has been in Windows longer than pktmon. Its characteristic is that as a “scenario” it can enable the whole set of ETW providers related to that problem at once.6

:: List available scenarios and inspect the providers in a scenario
netsh trace show scenarios
netsh trace show scenario netconnection

:: Start the capture. Packet capture included, 1GB circular buffer
netsh trace start scenario=netconnection capture=yes tracefile=C:\temp\nettrace.etl maxSize=1024 filemode=circular

:: Reproduce the incident, then stop (the merge takes a little time)
netsh trace stop
  • Add capture=yes to enable packet capture, and narrow the target with a capture filter such as ipv4.address=192.168.10.20. The filter list is in netsh trace show capturefilterHelp.6
  • Stopping produces a .cab file in addition to the ETL. The .cab holds system information such as adapter configuration and OS build, so it doubles as environment collection.6
  • Only one trace session can run at a time. Before you start another capture, check with netsh trace show status that no leftover session is still running.6
  • Add persistent=yes and the session survives a reboot. Capturing “communication fails for a moment right after reboot” or “the service connection at startup fails” — incidents you cannot start in time by hand — is netsh trace’s unique ground.5
Capturing a netsh trace scenarioStarting with a scenario enables a bundled set of ETW providers, capture=yes also captures packets, and stopping produces an ETL file and a .cab filecapture=yesStart with a scenarioEnable the provider setPackets are captured tooReproduce the incidentStopETL file.cab (system information)

Figure 7: Starting with a scenario enables a bundled set of providers, and stopping produces ETL and a .cab.

4.1. Making ETL Readable in Wireshark — etl2pcapng

netsh trace ETL cannot be opened in Wireshark as-is. etl2pcapng, the open-source tool Microsoft publishes on GitHub, converts packets inside an ETL captured with netsh trace start capture=yes to pcapng.2

etl2pcapng.exe C:\temp\nettrace.etl C:\temp\nettrace.pcapng

On conversion, etl2pcapng writes the process ID involved with each packet as a packet comment. Being able to see “which process’s traffic this is” in Wireshark helps when several apps on the same server are talking.2

The ETW-event side (Windows-internal events the scenario providers recorded) is not converted into pcapng. If you want the events as well, convert to text or similar with netsh trace convert input=C:\temp\nettrace.etl, or open the ETL in Windows Performance Analyzer.57

Reading netsh trace ETL splits into two pathsPackets inside the ETL convert to pcapng with etl2pcapng and are read in Wireshark; ETW events are not converted to pcapng, so you read them with netsh trace convert or Windows Performance Analyzeretl2pcapngnetsh trace ETLPacketsETW eventsConvert to pcapngRead in WiresharkProcess ID remains as a commentNot converted to pcapngRead with convert or WPA

Figure 8: Of the ETL, packets convert to pcapng to be read; ETW events are read by another means.

5. A First Look at Reading in Wireshark — Display Filters and TCP Analysis

Once you open the pcapng, first cut the noise with a display filter. Common ones are in the table.1213

Display filter Meaning
ip.addr == 192.168.10.20 Packets where this IP is source or destination
tcp.port == 8443 Packets that involve this TCP port
dns DNS queries and responses only
tcp.flags.syn == 1 && tcp.flags.ack == 0 Connect SYNs only
tcp.flags.reset == 1 RST (forced teardown) only
tcp.analysis.retransmission Packets Wireshark judged as retransmissions
tcp.analysis.zero_window Receive window 0 (the receiver cannot take more)
tcp.analysis.flags Every packet where some problem was detected

tcp.analysis.* are analysis flags Wireshark assigns by tracking TCP sequence numbers. Retransmissions, duplicate ACKs, out-of-order, ZeroWindow, and the like are picked up mechanically, so the standard way to start reading is to type tcp.analysis.flags first and list the “looks like a problem” places.13

In a timeout investigation, look for the following shapes in order.

  1. Did the three-way handshake complete? Are the three packets SYN → SYN/ACK → ACK all there? If SYN is repeated with no reply, it never reached the peer, or it was silently discarded in the middle (the typical firewall pattern).
  2. Which side sent the RST? An immediate RST to SYN means nobody is listening on the destination port; a RST after the connection is established means one side forced the connection down. The RST’s source IP is direct evidence of “who cut it”.
  3. Are retransmissions continuing? Repeated retransmission of the same segment is a sign that the acknowledgement (ACK) is not coming back to the sender. Whether the outbound data was lost or the returning ACK was lost cannot be settled from a one-sided capture (that is why “capture on both sides” in the next chapter matters). Retransmissions and timeouts are covered in more depth in “Why TCP Retransmissions Stall Industrial Camera Communication”.
  4. Is ZeroWindow present? That is a sign the receiving app is not reading from the socket and the receive buffer is full. It is grounds to suspect the receiving app’s design (“The Misconception That TCP Lets You Receive in the Same Units You Send”) rather than the network.
Order of shapes to look for in a timeout investigationConfirm three-way-handshake completion, presence and source of RST, continuing retransmissions, then ZeroWindow, to put a first mark on the causenoyesyesnoyesnoyesDid SYN get a reply?Never arrivedTypical firewallIs a RST present?RST source cut itRetransmits continue?ACK is not coming backZeroWindow present?Receiver not reading

Figure 9: Looking for handshake, RST, retransmission, then ZeroWindow in that order narrows where to look next.

Before you read packets one by one, it also helps to take in the whole picture with the statistics features. [Statistics] → [Conversations] is a list of “which IP pair / port pair talked, from when to when, how much”, so you can identify the conversation you care about and then filter to that conversation only. [Statistics] → [I/O Graph] is a volume graph over time; shapes such as “from this time, one direction went silent” jump out. Right-click the TCP conversation of interest and choose [Follow] → [TCP Stream] and you can read that connection’s exchange through as cleartext.

Take in the picture with statistics, then narrow to a conversationList which conversations talked when and how much in Conversations, grab the silent interval from the I/O Graph, filter to the conversation of interest, and read it through as a TCP streamTake in the whole picture with statisticsConversation list in ConversationsSee volume on the I/O GraphFilter to the conversation of interestThe silent interval becomes visibleRead through as a TCP stream

Figure 10: Before you read packet by packet, take in the picture with statistics, narrow to the conversation of interest, then read it through.

6. The Loopback Trap — Traffic to localhost Never Goes Through a NIC

Trying to investigate communication between apps on the same PC — for example a business app connecting to an intermediate service on localhost:8080 — and getting stuck at “nothing shows up in Wireshark” is a classic trap.

The cause is clear. Traffic to localhost (127.0.0.1) never goes through a physical NIC; it is turned around on the OS internal loopback path. A normal capture that targets a physical adapter therefore never sees it.9

Why traffic to localhost does not appear in a captureTraffic to localhost never goes through a physical NIC and is turned around on the OS internal loopback path, so it never appears in a normal capture that targets a physical adapterexternallocalhostAppNetwork stackPhysical NICSeen in normal captureTurned around in OSNot in normal captureNpcap loopbackor pktmon

Figure 11: Traffic to localhost is turned around before the NIC, so a physical-adapter capture never sees it.

There are two ways to deal with it.

  • When capturing in Wireshark: Choose Npcap’s “Adapter for loopback traffic capture” as the capture target. The Windows Wireshark installer (3.0 and later) bundles Npcap, so if Wireshark is already installed you can use it with no extra work.9
  • When capturing with the inbox tools: pktmon captures at multiple points inside the network stack rather than outside the NIC4, so it can observe loopback traffic as well. To be sure, before you set a production wait-for-repro, confirm on that machine with pktmon start -c -m real-time real-time display that the loopback traffic you care about is actually visible.

Watch for two mix-ups as well.

  • “localhost” can resolve to IPv6 ::1. The app is connecting to IPv6 ::1, but the investigator is looking only at 127.0.0.1 (IPv4) and wrongly concludes “there is no traffic”. Stretch the display filter across both, as in ip.addr == 127.0.0.1 || ipv6.addr == ::1, or make the app’s destination setting an explicit address.9
  • Traffic to your own real IP also never goes onto the wire. When the same PC connects from 192.168.10.5 to 192.168.10.5, the destination is a real IP but the OS still turns it around internally. Remember that “I specified a real IP, so it must go through the NIC” is not guaranteed.
The mix-up when localhost resolves to IPv6An app's localhost may resolve to IPv6 ::1, and if the investigator looks only at 127.0.0.1 they wrongly conclude there is no traffic, so stretch the display filter across both addresses or confirm the destination as an explicit addressApp connects to localhostActually resolves to ::1 (IPv6)Investigator looks only at 127.0.0.1Nothing appears on the screenStretch the filter across both addressesMake the destination an explicit address

Figure 12: Watch for the mix-up where localhost resolves to ::1 and looking only at 127.0.0.1 leads to “there is no traffic”.

7. Where to Capture — One Side, Both Sides, and Clock Sync

The value of a capture is decided by “where you captured”. The rule of thumb is as follows.

Capture location What you learn When it is a good fit
Client side only What you sent and what came back First, to get the overall picture. When you cannot touch the server
Server side only Whether the request arrived and whether a response was sent When there are many clients, or you cannot identify one
Both sides at once Where on the path a packet disappeared, which side went silent When you need to settle the responsibility boundary

A one-sided capture only tells you “the facts as seen from my position”. Continuing retransmissions on the client do not distinguish whether the sent packet vanished on the path, or arrived at the server and the reply vanished. Capture on both sides and line them up, and you can settle “the client sent it / the server never received it” — which side went silent. When you need to settle the responsibility boundary (the app, the OS, a network device, or the other end), it is worth staging a both-sides capture from the start.

What one-sided and both-sided captures tell youA one-sided capture cannot distinguish whether the outbound packet vanished or the returning reply vanished; capturing on both sides and lining them up settles which side went silentCapture on one sideFacts from your sideOutbound or return?Which one vanished?Capture on both sidesLine them upWhich side went silentNeed clock sync

Figure 13: One side only shows the facts you saw; lining up both sides is what first settles the responsibility boundary.

7.1. The Premise of Correlation Is Clock Sync

To line up captures from both sides, both machines’ clocks must agree. Before you start the capture, check and record the clock offset.

:: Check time-sync status (sync source, last sync time)
w32tm /query /status

:: Measure the offset against the peer server (5 samples)
w32tm /stripchart /computer:sv-app01 /dataonly /samples:5

w32tm /stripchart is the command that shows the time offset between you and the peer computer, and it becomes the grounds for a correction such as “the server clock was +0.8 seconds” when you line the captures up.14 In an environment with a large offset, fixing time sync first and then capturing is the shorter path in the end.

Procedure for checking the clock offset before correlationConfirm your own time-sync status with w32tm, measure and record the offset against the peer server with stripchart, use that offset as the grounds for correction when lining captures up, and if the offset is large fix time sync first and then captureCheck sync status with queryMeasure the offset with stripchartRecord the offsetGrounds for correction at correlation timeIf the offset is large, fix sync first

Figure 14: Measure and record the clock offset before you capture, and use it as the grounds for correction when you line the captures up.

7.2. For “We Do Not Know When It Will Happen” — a Ring Buffer

For an incident whose reproduction conditions are unknown, the basic move is to leave a ring buffer running and stop it when the incident occurs.

  • pktmon: The default is circular mode. Set the cap (MB) with --file-size; older packets are overwritten.8
  • netsh trace: Specify it as maxSize=1024 filemode=circular.5
  • Wireshark: Under [Capture] → [Options] → [Output] you can configure “multiple files + ring buffer”. It rotates by file size or time and keeps only the latest N files, so you can run for a long time with a disk-usage cap.15

In every case, share with the person on site the rule that when the incident happens, “note the time first, then” stop the capture. A ring buffer erases the past the longer you wait, so if the path from occurrence to stop is long, the interval you care about is overwritten.

Waiting with a ring-buffer captureFor an incident whose reproduction conditions are unknown, leave a ring buffer running, and when the incident occurs note the time and stop promptly; if you stop late, older packets are overwritten and the interval you care about disappearsStart a ring-buffer captureLeave it running and waitThe incident occursNote the timeStop promptlyOlder packets are overwrittenA late stop erases the interval you care about

Figure 15: A ring buffer erases the past the longer you wait, so once you have noted the time, stop promptly.

8. The Problem That TLS Hides the Payload — What You Can Still See

Most business traffic today is TLS (HTTPS). People tend to think “if it is encrypted, capturing is pointless”, but most of what you want in a timeout investigation is still visible with the encryption left in place.

  • Whether the TCP connection was established (three-way handshake)
  • How far the TLS handshake got — whether ServerHello came back to ClientHello, whether it was cut with a RST or an alert during the handshake
  • The destination host name on ClientHello (SNI), and the negotiated TLS version
  • After the connection is up, which side stopped sending. The location of the silence, retransmissions, RST, or a clean close (FIN)

In other words, isolating “cannot connect”, “drops in the middle”, and “no response comes back” almost never needs payload decryption. What encryption loses is “what they said”; “who went silent, and when” remains.

What a TLS capture can and cannot showEncryption hides only the application-data payload; TCP connect establishment, TLS handshake success or failure, SNI and TLS version, RST, and which side went silent remain visible with the encryption left in placeTLS traffic captureVisibleNot visibleTCP connect setupHandshake or RST?TLS result and SNIRST / who went silentApp-data payload

Figure 16: Encryption loses only the payload; the skeleton of the conversation is still readable with TLS left in place.

When you still need the payload, Wireshark can decrypt TLS using session keys written out through the SSLKEYLOGFILE environment variable. Support is limited to some implementations such as Firefox, Chrome, Chromium-based Edge, and OpenSSL-family libraries; Windows inbox SChannel (apps that use WinHTTP or WinINET) does not support this mechanism.10 Because “the session key is written to a file” means anyone who has that file can decrypt the whole conversation, this is not a production technique; treat it as reproduction and debugging in a development environment.

How SSLKEYLOGFILE decryption works and its limitsSession keys written via SSLKEYLOGFILE let Wireshark decrypt TLS, but only some implementations such as Firefox and the Chrome family support it and SChannel does not; anyone who has the key file can decrypt the conversation, so treat it as a development-environment-only techniqueSet SSLKEYLOGFILEWrite session keysRead in WiresharkKey holder can decryptDevelopment-onlySome TLS stacks onlySChannel: no support

Figure 17: Writing out session keys can decrypt, but supported implementations are limited, and the nature of the key makes it a development-environment-only technique.

When traffic goes through an internal proxy, the destination that appears in the capture is the proxy server, and TLS flows inside a CONNECT tunnel. The prior question of which proxy the app is even heading for is organized in the same-day companion article “Corporate Proxies and Windows Apps — Sorting Out Proxy Resolution in WinINET, WinHTTP, and .NET”.

9. Correlating with the App Log — Putting Time on the Same Axis

A capture by itself rarely produces the conclusion. The deciding move in practice is to put one line of the app log and one round-trip of packets on the same time axis.

The procedure looks like this.

  1. Identify the incident time from the app log (for example, a timeout exception at 10:23:41). If the timeout value is 30 seconds, the start should be around 10:23:11.
  2. Switch Wireshark’s time display to [View] → [Time Display Format] → [Date and Time of Day], and narrow the interval with a display filter (you can also filter by time, as in frame.time >= "2026-08-20 10:23:00" && frame.time <= "2026-08-20 10:24:00").
  3. In that interval, confirm the Chapter 5 order (handshake → RST → retransmission → ZeroWindow). If you can line it up as far as “30 seconds before the log’s timeout time, a SYN was sent, and after that only SYN retransmissions”, the log’s “timeout” is replaced by the observation “at this capture point, no reply came back at all” (whether the SYN never reached the peer, or the returning SYN/ACK was lost on the way back, cannot be settled from this capture point alone. If you need to settle it, capture on the server and line them up).
  4. Always correct the offset between capture time and log time (the clock offset you measured in Section 7.1, and the log’s timezone notation). A few seconds of correlation error will pin the wrong conversation as the culprit.
Procedure for lining up the app log and the packetsIdentify the incident time from the app log, work the start time backwards from the timeout value, narrow the interval in Wireshark with a display filter, confirm shapes in order, correct the clock offset, and put them on the same time axis1. Identify the incident time from the logWork the start backwards from the timeout value2. Narrow the interval with a display filter3. Confirm shapes in the Chapter 5 order4. Correct the clock offsetThe log's one word becomes an observation

Figure 18: Narrow the interval from the log time, confirm the shape, correct the clock offset, and put them on the same axis.

When you hand investigation results to a third party (a vendor, a carrier, the customer’s network staff), cutting the noise with a filter before you hand it over is both courtesy and a safety measure. In Wireshark, narrow to the conversation of interest with a display filter and save “displayed packets only” with [File] → [Export Specified Packets], and you get a small pcapng of just the range you need.

Finally, a handling caution. A capture file contains the communication itself. It can include credentials from cleartext protocols, HTTP cookies and API keys, the contents of mail or reports, and personal information. Decide the following three points as a set with the capture procedure.

  • Minimum-necessary capture: Narrow the target with the pre-capture filters (Chapters 3 and 4) and keep the time window as short as possible. Do not do “just capture everything” on a customer environment
  • Narrow before you hand it over: Export only the conversation of interest; do not include unrelated third-party traffic. If sensitive parts remain, agree with the recipient on masking or another means
  • Retention and deletion: Decide where capture files are kept, for how long, and when they are deleted, and delete them when the investigation is finished
Three decisions to make before you hand over a capture fileA capture contains the communication itself, so decide as a set with the capture procedure that you will narrow to the minimum with pre-capture filters and a time window, extract only the conversation of interest before handoff so unrelated traffic is not included, and decide retention location and period and delete after the investigationCapture = the trafficCapture the minimumHandoff or retention?Extract target firstSet retention, deleteFilter and export

Figure 19: Decide minimum capture, pre-handoff narrowing, and retention and deletion as a set with the capture procedure.

10. Summary

  • One layer below the app log’s “timeout” is the fact of the packets that actually went over the wire. Whether SYN got no reply, a RST tore the connection down, retransmissions continued, or ZeroWindow appeared changes where you look next.
  • Even on a site where you cannot install Wireshark, you can capture with Windows inbox pktmon and netsh trace. Capture with the inbox tool, read with Wireshark on your own machine — that split is the basic form.
  • pktmon is four steps: register a filter → pktmon start --capturepktmon stoppktmon etl2pcap. By default it is truncated to 128 bytes, so if you want the payload do not forget --pkt-size 0. Seeing drop location and reason is a strength only pktmon has.
  • netsh trace captures a bundle of ETW providers as a scenario, and with persistent=yes it can survive a reboot. Convert the ETL to pcapng with etl2pcapng to read it.
  • In Wireshark, start from tcp.analysis.flags and look for handshake, RST, retransmission, and ZeroWindow in that order. It is faster if you take in the picture with Conversations and the I/O Graph first, then narrow.
  • Traffic to localhost never goes through a NIC, so you cannot capture it the ordinary way. Use Npcap’s loopback adapter or pktmon’s in-stack capture.
  • Capture on both sides and line them up, and “which side went silent” is settled. The premise is clock sync (w32tm). For an incident whose reproduction conditions are unknown, wait with a ring buffer.
  • Even under TLS the skeleton of the conversation is visible. Treat decryption (SSLKEYLOGFILE) as a development-environment-only technique, and treat the capture file itself as confidential: build minimum capture, narrowing, and deletion into the operation.

Packet capture is often thought of as “a network specialist’s tool”, but in practice it is an app-side investigation tool that only starts to mean something when you line it up with the app log. The next time an investigation stops at the one word “timeout”, go look one layer down.

KomuraSoft LLC handles communication-origin bug investigations such as “the business app’s communication fails from time to time and we cannot find the cause” and “we want to isolate a connection error that happens only on the customer environment”. We take capture design (where, what, and how much to capture), Wireshark analysis, correlation with the app log, and the app-side fix as one continuous piece of work.

References

  1. Microsoft Learn, pktmon etl2pcap. On converting pktmon ETL logs to pcapng so they can be analyzed in Wireshark and similar tools, and on discard information and in-stack capture-point information being lost in pcapng, so you should narrow first with –drop-only or –component-id before converting.  2 3 4

  2. GitHub, microsoft/etl2pcapng. On etl2pcapng being Microsoft’s open-source tool that converts packets inside an ETL file captured with netsh trace start capture=yes and similar to pcapng, preserving interface information and writing the process ID as a packet comment.  2 3 4 5

  3. Microsoft Learn, Pktmon command formatting. On pktmon.exe being available on Windows 10 and Windows Server 2019 (version 1809) and later; the quick-start procedure of filter registration → start → reproduce → check counters → stop and convert; filters being at most 32, OR-combined, and not distinguishing source from destination; and discarded packets in the text output carrying a dropReason.  2 3 4 5

  4. Microsoft Learn, Packet Monitor (Pktmon). On Packet Monitor being Windows’ inbox cross-component diagnostic tool; capturing packets at multiple points inside the network stack to visualize a packet’s path; reporting discards at supported components with a drop reason (MTU Mismatch, Filtered VLAN, and so on); and providing per-point packet counters.  2 3 4

  5. Microsoft Learn, netsh trace. On netsh trace start parameters such as scenario, capture, tracefile, maxSize, fileMode (circular acting as a ring buffer), and persistent (keeping the session across a reboot), and on converting ETL to text and similar with netsh trace convert.  2 3 4 5

  6. Microsoft Learn, Using Netsh to manage traces. On a scenario being a predefined set of providers for troubleshooting; inspecting them with netsh trace show scenarios / show scenario; only one trace session being able to run at a time; packet filters such as ipv4.address when capture=yes; and stopping producing ETL and a .cab that includes system information.  2 3 4 5 6

  7. Microsoft Learn, Diagnose packet loss. On the official investigation procedure of first capturing a trace with pktmon and checking local drop reasons and statistics, combining that with protocol-level analysis in Wireshark, and if that is not enough moving on to a component-level trace with a netsh trace scenario.  2 3

  8. Microsoft Learn, pktmon start. On starting a capture with –capture; –pkt-size defaulting to 128 bytes and 0 recording the whole packet; –file-name and –file-size (default 512MB); and the –log-mode values (circular, multi-file, real-time, memory) with circular as the default.  2 3 4

  9. Wireshark Wiki, CaptureSetup/Loopback. On a normal capture targeting a physical NIC on Windows being unable to capture loopback traffic to 127.0.0.1; Npcap’s “Adapter for loopback traffic capture” making loopback capture possible; and Npcap being bundled in the Windows installer from Wireshark 3.0 onward.  2 3 4

  10. Wireshark Wiki, TLS. On Wireshark being able to decrypt TLS with session keys written out through the SSLKEYLOGFILE environment variable; support covering Firefox, Chrome, Chromium-based Edge, OpenSSL-family libraries, and similar; and Microsoft SChannel not supporting this mechanism.  2

  11. Microsoft Learn, pktmon counters. On pktmon counters displaying pass and drop counters per monitored component; –drop-reason displaying the most recent discard reason for each drop counter; and live updating with –live. 

  12. Wireshark, Building Display Filter Expressions (Wireshark User’s Guide). On display-filter syntax, field specifications such as ip.addr and tcp.port, comparison operators, and combining them with and/or/not. 

  13. Wireshark, TCP Analysis (Wireshark User’s Guide). On the list of Wireshark TCP analysis flags (tcp.analysis.retransmission, tcp.analysis.duplicate_ack, tcp.analysis.out_of_order, tcp.analysis.zero_window, and so on) and the conditions under which each is assigned.  2

  14. Microsoft Learn, Windows Time service tools and settings. On w32tm being the recommended command-line tool for configuring, monitoring, and troubleshooting W32Time, and on w32tm /stripchart displaying the time offset between you and a peer computer (options such as /dataonly and /samples). 

  15. Wireshark, Capture files and file modes (Wireshark User’s Guide). On capture-file output modes (single file, multiple files, ring buffer) and on a ring buffer keeping only the latest data so you can put a cap on disk usage. 

Recent articles sharing the same tags. Deepen your understanding with closely related topics.

These topic pages place the article in a broader service and decision context.

This article connects naturally to the following service pages.

Frequently Asked Questions

Common questions about the topic of this article.

How do I capture packets on a customer server where I cannot install Wireshark?
Use the inbox Windows tools pktmon or netsh trace and you can capture without installing extra software. With pktmon, register a filter in an elevated terminal, start the capture with pktmon start --capture, and stop it with pktmon stop. The resulting ETL file can be converted to pcapng with pktmon etl2pcap, so you can take the analysis back to Wireshark on your own machine. "Capture with the inbox tool, read with Wireshark" is the basic split on sites that restrict installs.
Should I use pktmon or netsh trace?
If the OS has pktmon (Windows 10 / Windows Server 2019 and later), start with pktmon. The commands are simple, you can see which network-stack component discarded the packet (the drop reason), and pcapng conversion is self-contained. netsh trace is the better choice when you are capturing on an older OS that does not have pktmon, when you want to collect Windows-component ETW events as a scenario, or when you want the capture to survive a reboot with persistent=yes. Microsoft's own troubleshooting material also points to this order: pktmon first, then netsh trace if that is not enough.
Why does traffic to localhost (127.0.0.1) not show up in Wireshark?
Traffic to localhost never goes through a physical NIC; it is turned around on the OS internal loopback path. A normal capture that targets a physical adapter therefore never sees it. In Wireshark, choose Npcap's "Adapter for loopback traffic capture" and you can capture loopback traffic. pktmon captures inside the network stack, so it can observe loopback traffic as well. Another common mix-up is that "localhost" resolves to IPv6 ::1, so a screen you are watching for 127.0.0.1 shows nothing — confirm by specifying the address explicitly.
Can I see the contents of HTTPS (TLS) traffic in a packet capture?
The application-data payload is encrypted and not visible. The "skeleton" of the conversation — TCP connect and disconnect, whether the TLS handshake succeeded, a RST teardown, which side stopped responding — is still visible even when encrypted, so most timeout investigations can proceed with TLS left encrypted. If you need the payload, decryption via SSLKEYLOGFILE exists, but it is supported only by some TLS implementations such as Firefox and the Chrome family; Windows inbox SChannel is not supported. The mechanism writes out secret-key material, so treat it as a development-environment-only option.
Is it safe to send a capture file to an external support desk?
Sending it as-is is dangerous. A capture contains the communication itself and can include credentials from cleartext protocols, cookies, API keys, and personal information. First, at capture time, narrow the filter and the time window to the minimum you need, and before you hand it over, extract only the target conversation with a Wireshark display filter and export that. For whatever still remains, agree with the recipient on how to handle sensitive parts (masking, or delivering them by another means) before you send it. Decide in advance how long capture files will be kept and when they will be deleted.

Author Profile

Profile page for the article author.

Go Komura

Representative of KomuraSoft LLC

Focused on Windows software development, technical consulting, and investigations into failures that are difficult to reproduce.

Back to the Blog