Protocol Modbus TCP · primary-source review 31 August 2026
Modbus TCP/IP Protocol: MBAP, Registers, Timing & Diagnostics
Modbus TCP carries a Modbus function and data payload inside a seven-byte MBAP header over a TCP connection. A correct implementation must correlate transactions, frame a TCP byte stream by the MBAP Length, translate documented register references into wire addresses, decode application values explicitly and detect data that has become stale.
The usual endpoint is TCP port 502, but a listening socket is only transport evidence. It does not prove the Unit Identifier, function, starting address, quantity, data representation, write authority or freshness contract. This guide shows how to prove every boundary with a repeatable transaction.

Answer first
What exactly is Modbus TCP?
The Modbus application specification defines the Protocol Data Unit: one function code plus function-specific data. The TCP messaging guide adds the MBAP header, assigns client/server transaction behavior and describes connection management. The resulting application data unit is sent through TCP. Unlike Modbus RTU, it has no serial station byte before the function and no RTU CRC after it; the MBAP Unit Identifier supports endpoint identification and gateway routing.
“Modbus TCP/IP” and “Modbus TCP” normally describe this same conventional mapping. Neither phrase means “any data sent on Ethernet,” and neither guarantees a particular PLC instruction, scan time, number of clients or security control. Those are implementation and system-design questions.
Separate the protocol from Ethernet, TCP and the PLC program
A useful troubleshooting model has five contracts. Ethernet proves local media and switching; IP proves addressing and routing; TCP proves a byte-stream connection; Modbus TCP proves MBAP and PDU behavior; the application contract proves that decoded data represents the intended process variable and is safe to use. A green port LED proves only part of the first contract. A successful ping reaches IP. A completed TCP handshake reaches a listening transport endpoint. Only a valid, correlated response to a known request proves the selected Modbus path.
| Layer | Required evidence | It does not prove | First capture fields |
|---|---|---|---|
| Ethernet | link at both ends, expected VLAN and switch path | IP route or Modbus service | ports, VLAN, link events, errors |
| IP | correct source/destination, subnet and routed path | TCP listener or usable register | addresses, route, loss and latency |
| TCP | SYN/SYN-ACK/ACK or product connection state | valid MBAP, function or data | ports, flags, resets, retransmission |
| Modbus TCP | complete MBAP/PDU and matched response | correct engineering meaning | transaction, protocol, length, unit, function |
| Application | documented type, scale, units, quality and age | field instrument or process truth | raw words, decoded value, quality, timestamp |

Decode the seven-byte MBAP header before touching a register
TCP is a byte stream. One receive operation may contain part of an ADU, exactly one ADU or several ADUs. A robust parser buffers bytes, waits for the complete fixed header, validates the Protocol Identifier and Length, then waits until the number of bytes declared by Length is present. It must not assume one Ethernet frame, one TCP segment or one socket read equals one Modbus message.
| MBAP field | Size | Meaning | Validation rule |
|---|---|---|---|
| Transaction Identifier | 2 bytes | Chosen by client; copied by server | Correlate to an outstanding request, not merely the oldest request |
| Protocol Identifier | 2 bytes | Zero for Modbus | Reject or flag an unexpected value |
| Length | 2 bytes | Bytes that follow, including Unit Identifier and PDU | Bound the value and wait for the complete declared message |
| Unit Identifier | 1 byte | Endpoint or gateway-routing context | Match exact endpoint/gateway configuration |
Byte-complete FC03 example
The following controlled request asks Unit Identifier 17 (`0x11`) to read three holding registers starting at protocol address 107 (`0x006B`). Transaction Identifier is 42 (`0x002A`). The request Length is six because it counts Unit Identifier plus a five-byte request PDU.
Request: 00 2A 00 00 00 06 11 03 00 6B 00 03
| TID | PID | Len |UI|FC| Start | Qty |
Response: 00 2A 00 00 00 09 11 03 06 02 2B 00 00 00 64
| TID | PID | Len |UI|FC|BC| three register words |The response Length is nine: one Unit Identifier, one function byte, one byte-count byte and six data bytes. The response returns raw words `0x022B`, `0x0000` and `0x0064`. Their engineering meaning is not defined by the frame. Only the controlled register map can say whether they are three independent unsigned integers, part of a 32-bit value, flags, a scaled measurement or something else. Download the transaction-vector CSV to check parser behavior.

Build a register contract that survives address and data-format ambiguity
The application specification describes coils, discrete inputs, input registers and holding registers. The request carries a zero-based address field inside a selected function. Manuals and client tools may instead show labels such as `40001`, offsets, tag names or one-based entries. Do not settle the difference through intuition. Store the manual label, Modbus table, wire address, client entry and proof value in separate columns.
A 16-bit register is just two data bytes at the protocol boundary. Multi-register types are application conventions. For every value define quantity, register order, byte order inside each word, signedness or IEEE format, scale, offset, unit, valid range, unavailable sentinel, write authority and freshness rule. Use deliberately asymmetric test patterns such as `0x1234` and `0x5678`; symmetrical or zero values can hide swaps.
| Contract field | Example | Failure prevented | Proof |
|---|---|---|---|
| role and endpoint | HMI client → PLC server 10.20.4.18:502 | two clients both acting as write owner | connection table and controlled write |
| unit/function | Unit 17, FC03 read | gateway route or table mismatch | captured request and server log |
| address representation | manual 40108; wire 107; client entry documented | off-by-one read of plausible neighbor | known changing test register |
| representation | two words, signed 32-bit, high word first | stable but numerically wrong value | asymmetric hexadecimal patterns |
| engineering transform | raw × 0.1 °C | tenfold control or display error | low/mid/high reference values |
| quality and age | bad after 1.5 s without good response | stale value shown as live | response interruption test |
| write authority | setpoint only; range 0–100; Auto mode only | unbounded or wrong-state command | allowed and prohibited writes |

Design transactions, scheduling and freshness as one state machine
A reliable PLC client does not fire a request every scan. It owns a transaction state: idle, issue, waiting, complete, failed, backoff and reconnect. The request trigger is usually an edge or controlled state transition. A result is consumed once. On timeout, the application classifies the failure, resolves that request, increments evidence counters and waits according to a bounded retry policy. Writes require stricter duplicate protection than reads because a reconnect must not silently repeat an action whose first outcome is unknown.
Connection handling and request handling are related but not identical. A socket may remain established while a server application stops responding. Conversely, a server may close idle connections and still be healthy. Track at least connection state, last request time, last good response time, consecutive failures, last exception, reconnect count and age of every published value group.
CASE TxState OF
Idle:
IF Due AND ConnectionReady THEN
TxId := NextTransactionId();
StartRequest := TRUE; // one controlled issue event
TxState := Waiting;
END_IF;
Waiting:
IF ResponseDone AND ResponseTxId = TxId THEN
ValidateMbapPdu();
DecodeOnlyIfValid();
LastGoodTime := Now;
TxState := Idle;
ELSIF ExceptionDone OR TransportError OR TimeoutExpired THEN
RecordFirstFailedBoundary();
InvalidateAffectedQuality();
TxState := Backoff;
END_IF;
Backoff:
IF BackoffExpired THEN TxState := Idle; END_IF;
END_CASE;
DataGood := LastDecodeValid AND (Now - LastGoodTime <= MaxAge);This is a behavior pattern, not a drop-in vendor block. Adapt it to the exact instruction's `BUSY`, `DONE`, `ERROR`, status and connection semantics. For a value consumed by the PLC or HMI, a conservative age budget includes client schedule wait, connection or recovery delay, network delay, server and controller-task processing, device update, decode and publication. Test the complete chain under representative load rather than quoting an Ethernet link rate as application performance.
| Poll class | Use | Design inputs | Overload action |
|---|---|---|---|
| fast operational | small set required for current control/supervision | required max age, server capacity, controller task | preserve critical set; shed lower classes |
| normal display | operator values and status | human-visible refresh requirement and grouping | increase interval with explicit age indication |
| slow configuration | settings, identity and maintenance counters | change frequency and consequence | poll on entry, change or long interval |
| write/command | setpoint or command handshake | authority, state permissive, acknowledgement, duplicate rule | fail closed and surface uncertain outcome |

Troubleshoot by the first boundary that disagrees
“Modbus is down” hides several mutually exclusive outcomes. No route, connection refused, TCP timeout, complete response with an exception, malformed MBAP, correct response with wrong value, and fresh-looking but stale application data require different corrections. Save the first disagreement before changing IP settings, register offsets and timeouts together.
| Observed symptom | First evidence | Likely boundary | Do not conclude yet |
|---|---|---|---|
| No TCP connection | route, firewall decision, SYN/SYN-ACK/RST, server listener | IP path, policy or service state | register address is wrong |
| TCP connects; no reply | complete request Length, unit/function/address, server counters | request framing, server load or downstream gateway | increase every timeout |
| Exception 01/02/03 | returned function+0x80 and exception byte | function, address or request value | the network failed |
| Exception 0A/0B | gateway route and downstream serial evidence | gateway path or target response | the TCP-facing gateway is the end device |
| Valid response; wrong value | raw words versus manual and independent reference | offset, word order, signedness or scaling | replace the switch |
| Value freezes without error | last-good timestamp, request schedule and publish logic | stale-data policy or request starvation | retained value is current |
| Intermittent under load | age distribution, timeouts, retransmissions, server/task counters | capacity, scheduling or network condition | one unloaded ping proves capacity |
| Duplicate command | transaction/write log across reconnect | retry and acknowledgement design | server ignored the first write |
For every failure, capture UTC/local timestamp context, client and server IP/port, connection event, Transaction Identifier, Protocol Identifier, Length, Unit Identifier, function, starting address, quantity, raw response or exception, client status, server/gateway counter, last-good age and the change made. The acceptance matrix provides a reusable starting record.

Commission a Modbus TCP client/server path in nine controlled gates
1. Freeze the scope
Record exact controller, firmware, communication module, engineering-tool version, client/server roles, endpoint and approved network zone.
2. Control the register map
Archive the device-map revision and create a machine-readable contract for every value used by logic, HMI, historian or maintenance tools.
3. Prove the endpoint
Verify switch/VLAN and IP path, the designed TCP service and endpoint diagnostics without exposing the service beyond the approved conduit.
4. Prove one read
Use one stable, documented value and save the byte-complete request and response before adding a large poll list.
5. Prove representation
Inject or observe asymmetric patterns, boundaries, negative values, invalid sentinels and engineering scaling.
6. Prove exceptions
Create controlled illegal-function/address/value cases and confirm the client distinguishes them from transport failure.
7. Prove age and recovery
Interrupt responses and connections; verify quality aging, backoff, reconnect and clean resumption without duplicate writes.
8. Prove representative load
Run every client, poll class and expected background load while measuring application age, server capacity and PLC task impact.
9. Freeze acceptance evidence
Save projects, maps, captures, results, deviations, security rules, owners and a restoration procedure under change control.
Security and safety boundary
Traditional Modbus TCP supplies application messaging, not a universal identity, role or write-authorization system. The existence of a writable register does not mean every reachable client should be allowed to change it. Place the communication in an approved OT architecture, restrict sources and destinations, minimize writable exposure, use endpoint access controls where the exact product supports them, monitor connection and write activity, and require PLC application-state permissives for consequential commands.
Modbus Security is a separate TLS/X.509 profile. Do not label an ordinary port-502 endpoint secure because it sits on an Ethernet network, and do not infer Modbus Security interoperability from a product's generic “Modbus TCP supported” claim. Verify client and server profiles, certificates, lifecycle, authorization and fallback behavior.
Communication success is not functional-safety validation. A simulator or protocol test can prove frame handling and application logic under modeled conditions; it cannot prove protective devices, field wiring, final elements, safety response time, risk reduction or compliance of an installed machine. Keep safety functions inside their engineered lifecycle and approved validation process.
Modbus TCP acceptance test matrix
Run positive, negative, boundary, timing and recovery cases. Record raw evidence and the first failed boundary, not just a green/red result.
| ID | Case | Method | Pass evidence |
|---|---|---|---|
| A01 | Known read | Read one documented register with the exact Unit Identifier, function, zero-based protocol address and quantity. | Response Transaction Identifier matches; function, byte count and decoded value match the contract. |
| A02 | Illegal function | Send one function the controlled test server documents as unsupported. | A Modbus exception is returned and classified; the client does not report a transport timeout. |
| A03 | Illegal address | Request a range just outside the documented map. | Exception and diagnostic log identify an application-address rejection rather than a network failure. |
| A04 | Transaction correlation | Issue permitted concurrent requests with distinct Transaction Identifiers. | Every response is paired with the correct request; no value is assigned by arrival order alone. |
| A05 | TCP stream split | Deliver one ADU across more than one TCP receive operation in a controlled harness. | The parser waits for the complete MBAP Length and does not parse a partial message. |
| A06 | TCP stream coalescing | Deliver two complete ADUs in one receive buffer. | Both are parsed exactly once; the second message is not discarded as trailing bytes. |
| A07 | Data representation | Exercise positive, negative, limit and known hexadecimal patterns. | Signedness, word order, byte order, scaling, units and quality match the register contract. |
| A08 | Write authority | Attempt an allowed write and a blocked or out-of-state write. | The intended write is proved end to end; the prohibited write is rejected or neutralized by the designed control layer. |
| A09 | Stale data | Stop responses while leaving the last good value in memory. | Quality changes after the specified age; the HMI or logic does not present the old value as current. |
| A10 | Disconnect recovery | Close or interrupt the connection during a transaction. | The client resolves the in-flight request once, backs off, reconnects and resumes without a write storm. |
| A11 | Load boundary | Run the approved poll set at design rate with representative server and network load. | Measured age, timeout, error and controller-task budgets remain inside requirements. |
| A12 | Security boundary | Test an unapproved source path and the approved engineering/client path. | Network and endpoint controls permit only the designed flows; logs retain source, destination and outcome evidence. |

Frequently asked questions
What is Modbus TCP?
Modbus TCP carries the Modbus application Protocol Data Unit through a Modbus Application Protocol, or MBAP, header over a TCP connection. It retains Modbus functions and data tables but replaces the Modbus RTU serial address and CRC wrapper with TCP/IP transport and an MBAP Unit Identifier.
Is Modbus TCP the same as Ethernet?
No. Ethernet describes lower network technologies. IP and TCP operate above Ethernet, and Modbus TCP is an application protocol carried over TCP. A working Ethernet link or successful ping does not prove that a Modbus service, function, unit, address or value is correct.
Which port does Modbus TCP use?
IANA registers TCP port 502 for the Modbus Application Protocol. A product can expose a configurable alternative, and Modbus Security is a distinct TLS-based specification associated with port 802. Follow the exact endpoint manual and approved OT policy rather than opening a port broadly.
Does Modbus TCP use a CRC?
The Modbus TCP ADU does not contain the two-byte Modbus RTU CRC. Ethernet and TCP have their own integrity mechanisms at other layers. A gateway can still report CRC faults on its downstream RTU segment.
What is the seven-byte MBAP header?
It contains a two-byte Transaction Identifier, two-byte Protocol Identifier, two-byte Length and one-byte Unit Identifier. The Length counts the Unit Identifier plus the following PDU bytes. The Protocol Identifier is zero for Modbus.
What is the Transaction Identifier used for?
A client assigns it to a request and the server copies it into the response. The client uses it to correlate a response with the correct outstanding request, which is important when an implementation permits more than one transaction in flight.
What Unit Identifier should I use?
Use the endpoint and gateway documentation. It is especially significant when a bridge routes a TCP request to a downstream serial device. Direct-server products differ, so values such as 0, 1 or 255 are not universal defaults.
Are 40001 and address 0 the same register?
Often a manual uses reference 40001 to describe the first holding register while the protocol request carries starting address 0, but software displays and device maps vary. Record table, documented reference, wire address and client entry separately, then prove one known value.
Does Modbus define 32-bit float word order?
No single Modbus-wide rule defines how a product combines two 16-bit registers into a 32-bit integer or floating-point value. The device map must define register order, byte order, signedness, scale and valid range.
Is Modbus TCP real time or deterministic?
The protocol does not provide one universal cycle-time guarantee. Observable data age depends on client scheduling, connection state, network load, server processing, PLC task timing, device update and application publication. Measure the engineered path under representative load.
Can several Modbus TCP clients connect to one server?
Many products allow it, but connection count, request capacity, write ownership and behavior under overload are product-specific. Validate the exact server and define a single authority for control writes.
Is ordinary Modbus TCP secure?
Traditional Modbus TCP does not by itself authenticate an operator or authorize a write. Use an approved OT architecture with segmentation, least-privilege conduits, endpoint controls where supported, monitoring and safe application-state permissives. Modbus Security support must be verified at both endpoints.
How do I diagnose a Modbus TCP timeout?
Separate name and route, TCP connection, MBAP/PDU, server processing, gateway downstream path and PLC application freshness. Capture timestamps, endpoints, connection events, Transaction and Unit Identifiers, function, address, quantity and server diagnostics before changing timeout values.
Can an online simulator validate a production Modbus TCP installation?
It can teach request construction, register decoding, exception handling and stale-data logic. It cannot validate the target driver, firmware, TCP stack, switch, firewall, gateway queues, device register map, process timing, physical installation or safety function.
Primary and official sources
Reviewed 31 August 2026. The Modbus Organization documents define protocol behavior. Vendor documents below are implementation examples for their named products, not universal claims about every Modbus TCP device.
- 1. Modbus specifications and implementation guides
Modbus Organization index for the controlled application, serial, TCP and security documents.
- 2. Modbus Application Protocol Specification V1.1b3
PDU, data model, public functions, address fields and exception responses.
- 3. Modbus Messaging on TCP/IP Implementation Guide V1.0b
MBAP header, transactions, connection management, client/server and gateway behavior.
- 4. Modbus TCP Conformance Test Specification V3.0
Conformance cases and direct-server versus downstream Unit-Identifier context.
- 5. Modbus TCP conformance testing program
Product conformance scope; project acceptance remains separate.
- 6. Modbus TCP toolkit
Official implementation and diagnostic resources.
- 7. Modbus Organization FAQ
Protocol ownership and performance qualification.
- 8. Modbus Security Protocol
Distinct TLS and X.509 security profile.
- 9. IANA service-name and port-number registry
Registered Modbus service ports.
- 10. RFC 9293: Transmission Control Protocol
Current TCP protocol specification and byte-stream context.
- 11. NIST SP 800-82 Rev. 3
OT security architecture and operational-technology control context.
- 12. Siemens S7-1200/S7-1500 communication manual
Product-specific Modbus TCP client/server parameters and status behavior.
- 13. Siemens WinCC communication manual
HMI-side Modicon Modbus TCP configuration and product limits.
- 14. Schneider Electric Modbus TCP IOScanner settings
Product-specific repetition rate, health timeout and exchange configuration.
- 15. Schneider Electric Modbus TCP server access rules
Example endpoint access restrictions; not a universal Modbus feature.
- 16. CODESYS Modbus TCP client configuration
Response timeout, reconnect and implementation settings.
- 17. CODESYS Modbus client request behavior
Request lifecycle, reply timeout and starvation behavior.
- 18. Schneider Electric Ethernet gateway implementation
Product example for TCP Unit-Identifier forwarding to serial devices.