Modbus TCP MBAP Header & Message Format Reference

Complete reference for the Modbus TCP message format — MBAP header fields, Transaction ID management, Unit Identifier usage, TCP connection handling, and differences from Modbus RTU framing.

Categories:

Overview

Modbus TCP wraps the standard Modbus protocol data unit (PDU) inside a TCP/IP packet using the MBAP header (Modbus Application Protocol header). This header replaces the slave address and CRC/LRC fields used in Modbus RTU and ASCII serial modes.

Understanding the MBAP header is essential for debugging Modbus TCP communication with Wireshark, configuring TCP-to-RTU gateways, and implementing custom Modbus TCP clients or servers.

Modbus TCP MBAP Header Format

MBAP Header Structure

The MBAP header is 7 bytes prepended to every Modbus TCP request and response:

FieldSizeByte PositionDescription
Transaction Identifier2 bytes0–1Request/response correlation ID (set by client)
Protocol Identifier2 bytes2–3Always 0x0000 for Modbus
Length2 bytes4–5Number of bytes following (Unit ID + PDU)
Unit Identifier1 byte6Slave/device address (or 0xFF for direct TCP devices)

Complete Modbus TCP Frame

[MBAP Header (7 bytes)] + [Function Code (1 byte)] + [Data (N bytes)]
ComponentSizeExample (Hex)
Transaction ID2 bytes00 01
Protocol ID2 bytes00 00
Length2 bytes00 06
Unit ID1 byte01
Function Code1 byte03
Data4 bytes00 00 00 01
Total12 bytes00 01 00 00 00 06 01 03 00 00 00 01

This example reads 1 holding register starting at address 0 from Unit ID 1.

Field Details

Transaction Identifier

PropertyDetail
Set byClient (master)
Echoed byServer (slave) — must match in response
PurposeCorrelates requests with responses for concurrent communication
Typical valuesSequential counter: 0x0001, 0x0002, 0x0003

The Transaction ID allows a client to send multiple requests without waiting for each response — the client matches responses to requests using the ID. This enables pipelining that is impossible in serial Modbus RTU (which is strictly request-response).

[!TIP] When debugging with Wireshark, filter by Transaction ID to match a specific request with its response. If response Transaction IDs don’t match request IDs, the server implementation has a bug.

Protocol Identifier

PropertyDetail
ValueAlways 0x0000 for standard Modbus
PurposeAllows multiplexing with other protocols on the same TCP connection
In practiceAlways zero — no other protocols use this field

[!NOTE] A non-zero Protocol Identifier indicates either a non-standard Modbus variant, a protocol implementation bug, or packet corruption. Standard Modbus TCP clients and servers should reject frames with Protocol ID ≠ 0.

Length

PropertyDetail
CoversUnit Identifier + Function Code + Data
Does NOT coverTransaction ID + Protocol ID + Length field itself
Minimum0x0002 (Unit ID + Function Code with no data)
Maximum0x00FD (253 — Unit ID + FC + 251 bytes of data)

The Length field tells the receiver how many bytes follow the Length field itself. It enables the receiver to detect complete frames within the TCP byte stream.

Unit Identifier

PropertyDetail
PurposeIdentifies the target device when multiple devices share a single TCP connection
For direct TCP devicesTypically 0xFF (255) or 0x01 (1) — device-specific
For TCP-to-RTU gatewaysMaps to the RTU slave address on the serial side
Broadcast0x00 — see broadcast addressing

[!WARNING] The Unit Identifier in Modbus TCP serves the same purpose as the slave address in Modbus RTU, but they are handled differently. In RTU, a device only responds to its own address. In TCP, the gateway uses the Unit Identifier to route the request to the correct serial device. If the Unit Identifier doesn’t match any downstream serial device, the gateway returns exception 0A or 0B.

Modbus TCP vs Modbus RTU: Key Differences

FeatureModbus RTU (Serial)Modbus TCP (Ethernet)
TransportRS-485 / RS-232TCP/IP (Ethernet)
Default portN/A (serial)502
Error checkCRC-16 (2 bytes)None — relies on TCP checksums
FramingSilent intervals (timing-based)MBAP header (Length field)
Device addressSlave Address (1 byte, in frame)Unit Identifier (1 byte, in MBAP header)
Concurrent requestsNo — strict request/responseYes — Transaction IDs enable pipelining
Max PDU size253 bytes253 bytes (same)
Connection managementN/A (bus is always on)TCP connection setup/teardown

No CRC in Modbus TCP

Modbus TCP does not include its own CRC or checksum. Error detection is provided by:

  1. TCP checksum — covers the entire TCP segment (header + payload)
  2. Ethernet FCS — frame check sequence at the data link layer

This means CRC errors are never a problem on Modbus TCP. If you see corrupted data over Modbus TCP, the issue is at the application layer (wrong register map, byte order, or scaling), not the transport layer.

TCP Connection Management

Default Port

Modbus TCP servers listen on TCP port 502. Some devices allow configuring an alternate port for security or multi-instance scenarios.

Connection Limits

ParameterTypical ValueNotes
Max simultaneous connections1–8Device-dependent — cheaper devices may support only 1
Connection timeout30–120 secondsServer drops idle connections
Keep-aliveTCP keep-alive recommendedPrevents stale connections after network interruptions

[!CAUTION] Many embedded Modbus TCP devices support only 1 or 2 simultaneous TCP connections. If your gateway opens a connection and a maintenance laptop also connects, the device may reject the gateway’s connection. Coordinate access to avoid connection conflicts.

Connection Lifecycle

  1. Client opens TCP connection to server on port 502
  2. Client sends MBAP + PDU — one or more Modbus requests
  3. Server processes and responds — MBAP header echoes the Transaction ID
  4. Connection stays open — multiple request/response cycles on the same connection
  5. Connection closes — either side can close after an idle timeout

[!TIP] For gateway devices, configure persistent connections (keep the TCP connection open between polls) rather than opening and closing for each request. This reduces latency and avoids TCP handshake overhead.

Example: Wireshark Analysis

Capture Filter

To capture only Modbus TCP traffic:

tcp port 502

Display Filter

To filter Modbus TCP frames in a capture:

mbtcp

Reading a Modbus TCP Frame in Wireshark

Wireshark natively decodes the MBAP header and PDU:

Wireshark FieldCorresponds To
mbtcp.trans_idTransaction Identifier
mbtcp.prot_idProtocol Identifier (should be 0)
mbtcp.lenLength
mbtcp.unit_idUnit Identifier
modbus.func_codeFunction Code
modbus.regnum16Starting register address
modbus.word_cntNumber of registers requested

Filtering for Errors

Show only exception responses:

modbus.func_code >= 0x80

Show responses from a specific Unit ID:

mbtcp.unit_id == 1

TCP-to-RTU Gateway Translation

When a QuickServer operates as a Modbus TCP-to-RTU gateway:

Request Path (TCP → Serial)

ActionDetails
Receive MBAP + PDU from TCP clientParse Transaction ID, Unit ID, Function Code, Data
Store Transaction IDNeeded to build the response
Build RTU frame[Unit ID] [FC] [Data] [CRC-16]
Send on serial portRS-485 at configured baud rate

Response Path (Serial → TCP)

ActionDetails
Receive RTU frame from serial device[Slave Addr] [FC] [Data] [CRC-16]
Verify CRCDiscard frame if CRC invalid
Strip CRC and slave addressKeep FC + Data
Build MBAP headerUse stored Transaction ID, Protocol ID = 0, Length = 1 + FC + Data length
Send TCP responseRoute to the TCP client that made the request

Timing Considerations

ParameterTCP SideRTU Side
Response timeout1–5 seconds typical100–500ms typical
Concurrent requestsSupported (via Transaction IDs)Not supported (one at a time on serial)
QueueingGateway queues TCP requestsSends serial requests sequentially

[!NOTE] When multiple TCP clients send requests to the same serial device, the gateway serializes them on the RS-485 bus. This means TCP response times include queueing delay — each request must wait for all previous serial requests to complete. Monitor total poll cycle time to ensure it stays within acceptable limits.

Common Configuration Issues

ProblemSymptomFix
Wrong TCP portConnection refusedVerify device is listening on port 502 (or the configured port)
Unit ID doesn’t match deviceException 0A/0B from gateway; no response from direct deviceCheck the device’s expected Unit ID in its documentation
Connection limit exceededConnection drops or refusedDisconnect unused Modbus TCP clients; check device max connection count
Firewall blocking port 502Connection timeoutOpen TCP port 502 inbound on the firewall
Transaction ID mismatchResponses assigned to wrong requestsClient-side bug — verify the client increments Transaction IDs correctly
Stale TCP connectionTimeouts after network interruptionEnable TCP keep-alive; implement reconnection logic

Chipkin Tools

Need more help?

If this page does not resolve the issue, contact Chipkin support with the product model, protocol details, and any diagnostics you have already captured.

Open Chipkin Support