Page review information
Edition covered
Modbus.org — Modbus Application Protocol / Modbus TCP — exact governing revision not yet recorded
Content status
Reviewed
Coverage
Covers Modbus TCP register model, polling, and diagnostics; Modbus RTU/ASCII serial variants and Modbus Security are noted but not covered in depth
Last reviewed
August 2026
Primary reference
The official published standard — required for final decisions

Confirm the applicable specification revision, device firmware, vendor implementation, network architecture, cybersecurity requirements, and project-specific constraints before applying anything on this page.

Overview

Modbus TCP wraps the Modbus application protocol (maintained by Modbus.org) in a TCP connection on port 502. It is a client/server protocol: the client (historically “master”) sends a request, the server (historically “slave”) answers it. There is no cyclic connection, no device description file, and no producer/consumer model — just polled register reads and writes. That simplicity is why it survives everywhere, and why its failure modes are almost always about addressing and data interpretation rather than the protocol itself.

One distinction the terminology often blurs: Modbus is an application protocol; RS-485 is an electrical physical layer. Modbus RTU commonly runs over RS-485, but Modbus TCP runs over ordinary Ethernet — the two should never be treated as interchangeable terms.

flowchart TD
    SCADA[SCADA / Historian<br>Modbus TCP client] --> SW[Managed Switch]
    PLC[PLC<br>Modbus TCP client] --> SW
    SW --> PM[Power Meter<br>server, unit ID ignored]
    SW --> VFD[VFD<br>server]
    SW --> GW[Serial Gateway<br>TCP 502]
    GW -- "RS-485, Modbus RTU" --> S1[Instrument, unit ID 1]
    GW -- " " --> S2[Instrument, unit ID 2]
    GW -- " " --> S3[Instrument, unit ID 3]

Where It Is Used

Scope notes: Modbus has no device profiles — every vendor’s register map is different, so the device manual is always the authority. Data beyond 16-bit registers (floats, 32-bit counters, strings) is a vendor convention, not part of the specification.

Network Design

Table Access Typical use
Coils Read/write, 1 bit Discrete outputs, command bits
Discrete inputs Read-only, 1 bit Discrete status inputs
Input registers Read-only, 16 bit Measured values
Holding registers Read/write, 16 bit Setpoints, configuration, and (in practice) most vendor data
FC Action Table
01 / 02 Read coils / read discrete inputs Bits
03 / 04 Read holding registers / read input registers 16-bit registers
05 / 06 Write single coil / single register One item
15 / 16 Write multiple coils / multiple registers Block writes

A server that cannot honor a request returns an exception response (function code + 0x80, plus an exception code such as 01 illegal function, 02 illegal data address, 03 illegal data value). Not every device implements every function code — many meters support only FC03/FC04.

Configuration

  1. Assign the IP address on the server device (web page, display keypad, or vendor utility) and record it in the address plan.
  2. Obtain the register map from the device manual. Record register table, address, data type, scaling, and word order for every point — this document is the Modbus equivalent of a device description file, and you have to write it yourself.
  3. Check the addressing convention. Documentation may be 0-based protocol addresses or 1-based register numbers (e.g., “40001” style for holding registers). A consistent off-by-one across all points almost always means the two conventions were mixed.
  4. Handle 32-bit values. Floats and 32-bit integers span two consecutive registers, and the specification does not define which register holds the high word. If a float decodes as an absurd value (e.g., 5.8e-39) or a large counter jumps erratically, try swapping word order in the client before suspecting the device.
  5. For gateways: map unit IDs to RS-485 slave addresses, set the serial parameters (baud, parity, stop bits) to match every slave, and set the gateway’s RTU response timeout below the TCP client’s timeout.

Worked Example — “Register 40001” vs Protocol Address 0

The single most common Modbus integration error is the off-by-one between documentation addressing and protocol addressing:

Device manual says:      holding register 40001
On the wire that is:     function code 03, starting address 0
Data type:               IEEE-754 float
Length:                  2 registers (one 32-bit value)
Word order:              high word first (vendor-specific — verify)

The 4xxxx convention is a documentation habit: the leading 4 means “holding register,” and the numbering starts at 1. The protocol itself sends a zero-based offset. Software that expects the raw offset will read the wrong register if you type 40001 into it — and software that expects the 4xxxx form will be off by one if you type 0. When a value looks plausible but wrong (or two values are swapped), suspect this and the word order before anything else.

Commissioning Checks

Diagnostics

Layered approach: confirm the TCP layer first (ping, then whether the three-way handshake on port 502 completes), then the Modbus layer (does the server answer at all; does it answer with exceptions), then the data layer (are the values right). A refused or reset connection is a networking/security problem; an exception response is an addressing/configuration problem; wrong values with clean communication are a data-interpretation problem.

Modbus TCP is fully capturable in Wireshark. Capture on the client machine when the client is a PC; use switch port mirroring when it is a PLC. Useful display filters (verify filter names against the Wireshark version in use):

modbus
mbtcp
tcp.port == 502
modbus.exception_code
tcp.flags.reset == 1
tcp.analysis.retransmission

modbus.exception_code isolates exception responses immediately — the exception code plus the request it answers usually identifies the fault without further work. The Wireshark dissector also decodes function codes and register addresses (as 0-based protocol addresses, which helps settle offset disputes).

What Wireshark cannot see: anything on the RS-485 side of a serial gateway. If the gateway answers with timeouts or gateway exceptions, the fault is on the serial segment — that requires the gateway’s own diagnostics, an isolated USB-to-RS-485 adapter with a serial monitor, or in stubborn cases an oscilloscope on the A/B pair. A clean TCP capture proves nothing about the serial side.

Wireshark Workflow

  1. Filter mbtcp || modbus — identify which end is client (sends requests) and which is server
  2. Match request/response pairs by transaction identifier
  3. Confirm the function code, starting address, and quantity actually on the wire match what the integration documentation claims
  4. Look for exception responses (modbus.exception_code) — an exception is the server answering “no,” which is a configuration problem, not a network problem
  5. Measure request→response time; then check TCP retransmissions (tcp.analysis.retransmission) separately — slow responses and lost packets have different owners
  6. Silence (no response at all) with a healthy TCP session points at unit ID or gateway routing rather than the TCP path

Common Faults

Symptom Likely causes First checks
TCP connect refused / times out Wrong IP, firewall blocking 502, device connection limit reached, server function disabled Ping, then tcp.port == 502 capture — SYN with no answer vs RST tells you which
Exception 01 (illegal function) Device does not support that function code (e.g., FC04 on a holding-register-only device) Device manual’s supported-FC list; switch FC03/FC04
Exception 02 (illegal data address) Register offset wrong — usually the 0-based vs 1-based documentation mismatch, or read past the end of a block Compare request address in capture against the manual’s convention; try ±1
Exception 03 (illegal data value) Write value out of range, or wrong register count in a block request Device limits for that register; block size
Exception 0x0A / 0x0B via gateway Gateway can’t reach the RTU slave: wrong unit ID, serial parameters, wiring, or slave offline Gateway diagnostics page; RTU-side serial settings and termination
Values wrong but communication clean Word order on 32-bit values, byte order, scaling factor, signed/unsigned mix-up Read a known value; swap word order first — it is the most common culprit
All points shifted by one register 0-based vs 1-based convention mixed between register map and client config Fix the convention globally, not point by point
Intermittent timeouts through gateway Client timeout shorter than gateway RTU round-trip, too many clients, RS-485 fault on the serial side Gateway timeout settings; serial-side diagnostics (out of Wireshark’s view)
Trust Boundary — Engineering Judgment Required

This site is an independent educational reference for industrial automation standards. It paraphrases and organizes guidance in original language; it is not a substitute for the official published standards, professional engineering judgment, or legal review, and content has not been independently verified against current published editions.

Items marked Review pending await technical review against the identified edition. Items marked Planned have no reviewed source material behind them. Do not rely on this site for compliance determinations, safety-critical design decisions, or legal interpretation.