Analyze Modbus TCP with Wireshark: Capture & Troubleshooting Guide
QModMaster’s Bus Monitor shows you every frame your PC sends and receives — and that is enough for most day-to-day debugging. But sometimes the problem is not in your PC at all: it is on the wire, in a switch, in a gateway, or in a second master fighting you for the same device. That is when you graduate from the Bus Monitor to Wireshark.
Think of it this way: the Bus Monitor sees what your machine sent and got back. Wireshark sees everything that crosses the network interface — TCP handshakes, retransmissions, RST packets, and traffic from other masters you did not know were polling. This guide walks you through capturing and reading Modbus TCP in Wireshark, and the exact workflow for pairing it with QModMaster.
1. Capture Setup: Grab Modbus TCP Traffic
- Pick the right interface. Open Wireshark and select the network interface that is actually connected to your Modbus network (the Ethernet NIC facing the plant LAN, not a VPN or loopback adapter). If your PC has several, check which one carries the device’s subnet.
- Set a capture filter. In the capture options, enter
tcp port 502before you start. This tells Wireshark to record only Modbus TCP traffic, which keeps capture files small and analysis fast on a busy network. - Capture at the master. The simplest and most useful capture point is the PC running QModMaster — you get the full picture of what the master sees.
- Let it run a full poll cycle. Start the capture, run your QModMaster poll for at least one full cycle (typically 5–30 seconds), then stop and save the file.
- Non-standard ports. Wireshark only auto-decodes Modbus on port 502. If your device uses a custom port (e.g. 1502 or 8502), the packets will show as raw TCP. Fix it with Decode As…: right-click a packet → Decode As → set the TCP port value → choose MBTCP. From then on, everything on that port decodes as Modbus.
2. The Display Filters You Will Actually Use
Type these into Wireshark’s display filter bar. They are verified against Wireshark’s official display filter reference:
| Filter | What it shows |
|---|---|
modbus | All Modbus traffic — requests plus responses |
tcp.port==502 | Everything on port 502, including the TCP handshake |
modbus.func_code==3 | Only Read Holding Registers traffic |
modbus.exception_code | Packets carrying an exception code (error responses) |
modbus.func_code>=128 | All exception responses (function code + 0x80) |
mbtcp.trans_id | Filter by MBAP transaction identifier |
mbtcp.unit_id==1 | Only traffic to/from Unit ID 1 |
modbus.reference_num==100 | Requests targeting a specific register address |
Combine them when you need precision: modbus.func_code==3 && mbtcp.unit_id==5 shows only FC03 traffic to unit 5. And modbus && ip.addr==192.168.1.100 isolates one device on a noisy network.
3. Pair Requests and Responses by MBAP Transaction ID
Every Modbus TCP frame starts with a 7-byte MBAP header, and its first field is the Transaction Identifier. The master assigns a transaction ID to each request; the slave echoes the same ID back in its response. In Wireshark’s packet list you will see pairs like:
Response: Trans: 1; Unit: 1, Func: 3: Read Holding Registers
Query: Trans: 2; Unit: 1, Func: 3: Read Holding Registers
Response: Trans: 2; Unit: 1, Func: 3: Read Holding Registers
This pairing is your single most powerful diagnostic tool:
- A Query with no matching Response = the request reached the wire but nothing came back. Check the TCP layer: did you get a SYN-ACK? If yes, the device accepted TCP but its Modbus service never answered. If you see a TCP RST instead, the device (or a firewall) actively refused.
- A Response whose transaction ID matches an older Query = delayed or out-of-order delivery. Sort the packet list by transaction ID and the misalignment jumps out immediately.
- Two Queries in a row before any Response = the master fired the next request too early (overlapping requests), which can desync response matching.
- Response arrives hundreds of milliseconds late = the device is slow or overloaded. Add a delta-time column (frame.time_delta) and filter
modbus && frame.time_delta > 0.5to find every slow response in one pass.
4. Spot Exception Frames (Function Code + 0x80)
When a slave cannot fulfill a request, it answers with an exception frame: the function code comes back with 0x80 added (so FC03 becomes 0x83), followed by a one-byte exception code. In the Wireshark packet list these stand out immediately, and the filter modbus.func_code>=128 isolates them. The most common exception you will meet is code 02 (Illegal Data Address) — it almost always means the requested register does not exist on the device, typically an off-by-one in your address mapping. For a full breakdown of all exception codes, see our exception codes guide.
5. The Practical Workflow: QModMaster + Wireshark Together
- Step 1 — Reproduce in QModMaster. Set up the failing poll exactly as it happens in production: same slave ID, same function code, same registers. Confirm the symptom (timeout, wrong values, exception).
- Step 2 — Capture in Wireshark. Start a capture with
tcp port 502on the right interface, run the failing poll once, stop the capture. - Step 3 — Cross-check against the Bus Monitor. Open QModMaster’s Bus Monitor side by side. Do the raw frames match what Wireshark captured? If the Bus Monitor shows a response that Wireshark does not, something between the socket and the capture layer is off — rare, but this comparison is how you prove it either way.
- Step 4 — Pinpoint with filters. Now work the capture: pair transaction IDs, hunt exception frames, measure response times, look for retransmissions (
tcp.analysis.retransmission && tcp.port==502) and resets (tcp.flags.reset==1 && tcp.port==502). Each pattern points at a different cause — network loss, a dead Modbus service, a competing master, or a slow device.
One honest boundary: everything above covers Modbus TCP, where Wireshark is free and excellent. If your problem is on the serial RTU side, Wireshark cannot see it — there are no packets on a serial line. For that, step up to a hardware logic analyzer that captures the actual RS-485 waveforms:
Debugging serial RTU? Wireshark can’t help there.
A logic analyzer captures the real RS-485 traffic. For Modbus TCP, Wireshark (free) is all you need.
See Logic Analyzer Options