Overview: S7-1500 Modbus TCP Client Status 8383 / 7004
When a Siemens S7-1500 CPU 1513-1 PN (firmware V1.1, but the same logic applies to firmware V2.x, V3.0, and the entire S7-1500/ET 200SP CPU family) is configured as a Modbus TCP client and connected to a Modbus server such as MODSIM32, Modbus Poll, or a real PLC server, the most common symptom in TIA Portal online watch tables is the MB_CLIENT STATUS output toggling between two values:
-
W#16#7004— "Connection established and monitored. No job processing active." -
W#16#8383— "Error reading or writing data or access outside the address area of MB_DATA_PTR."
Engineers who see this pattern for the first time frequently assume a network or firewall problem. In the overwhelming majority of cases, however, the TCP connection is healthy and the toggling is a buffer-sizing problem on the data side. The connection was established once (7004 confirms this), but every time the client tries to push a read or write job the server (or the client buffer) reports the address is out of range (8383).
This article walks through the diagnostic logic, root-cause matrix, and step-by-step fix using the Siemens MODBUS TCP library for S7-1200/S7-1500 — covering library versions V3.x and V4.0+, including the latest Description of MB_CLIENT (S7-1200, S7-1500, S7-1200 G2) reference documentation in the TIA Portal help system.
Decoding the Two Status Codes
W#16#7004 — Idle/Established, Not a Fault
The status word 16#7004 from MB_CLIENT is a transient, expected value. Per the Siemens MODBUS TCP manual, it is reported when:
- The TCP connection between the S7-1500 client and the server has been opened successfully.
- The connection is being monitored by the block (heartbeat / keep-alive handling).
- No Modbus request job is currently in flight on this call cycle.
If you see only 7004 in the online view, the client is correctly idle — your job trigger (REQ) is not pulsing, or you are looking between two job cycles. A persistent 7004 that never becomes 16#0000 on a successful job usually points at the trigger logic, not at the network.
W#16#8383 — Address / Buffer Out-of-Range
The status word 16#8383 is the error code emitted by MB_CLIENT when the block cannot complete a read or write because the destination buffer at the client (MB_DATA_PTR) is too small, the source holding-register buffer at the server (MB_HOLD_REG) is too small, or the requested register range lies outside the configured HR_Start_Offset window. The same code is also produced by MB_SERVER when it receives a request that targets a register outside its own MB_HOLD_REG area.
Because the error is raised per job, you will typically see the status oscillate: 7004 between requests, 8383 on the rising edge of REQ when the job is dispatched and rejected. The DONE bit never latches TRUE; the ERROR bit latches TRUE on every cycle.
Root-Cause Matrix
| # | Root Cause | Where to Check | Typical Symptom |
|---|---|---|---|
| 1 | Server MB_HOLD_REG buffer too small | MB_SERVER instance DB → MB_HOLD_REG length | 8383 on every read/write; partial data when N is small |
| 2 | Client MB_DATA_PTR buffer too small | MB_CLIENT instance DB → MB_DATA_PTR target length | 8383 when MB_DATA_LEN > buffer |
| 3 | HR_Start_Offset mismatch | MB_SERVER instance DB → HR_Start_Offset | 8383 for low register numbers when offset is non-zero |
| 4 | MODSIM address window too narrow | MODSIM32 → File → New → Register Definition | 8383 on the first N+1 register read |
| 5 | REQ trigger never pulses | OB1 / cyclic OB → REQ input rising edge | 7004 only, never 0000 or 8383 |
| 6 | MB_DATA_LEN wrong unit | MB_CLIENT → MB_DATA_LEN input | 8383 on small N; success on N=1 |
| 7 | Optimized DB access (legacy lib) | DB properties → Attributes | Compile error or 8383 / 80B1 on first job |
| 8 | Library / firmware mismatch | TIA Portal → Libraries → MODBUS TCP version | Block fails to instantiate or 80C1 on connect |
Prerequisites
- CPU: S7-1500 CPU 1513-1 PN (6ES7513-1AM02-0AB0) at firmware V1.1 or later. The same procedure applies to CPU 1511-1 PN, 1515-2 PN, 1516-3 PN/DP, 1517-3 PN/DP, 1518-4 PN/DP, and the ET 200SP CPUs 1510SP-1 PN / 1512SP-1 PN.
- TIA Portal: V15.1 minimum; V16, V17, V18, V19, or V20 recommended for current MB_CLIENT library features and online diagnostics.
- Modbus TCP library: "MODBUS TCP" library (FB 1300-class blocks) — see the Siemens entry 109769202 on the Industry Online Support. Library V3.x is required for S7-1500 firmware V2.0+; library V4.0+ is required for S7-1200 G2 and S7-1500 firmware V3.0+.
- Modbus server: MODSIM32, Modbus Poll, an MB_SERVER on a second S7-1500, or any third-party Modbus TCP server.
- Network: PC with the Modbus server reachable on the same subnet as the CPU's PROFINET interface X1 (e.g., CPU 192.168.0.10, server 192.168.0.50, subnet 255.255.255.0).
- Online access: Ethernet PG/PC interface routed to the CPU, online watch table available in TIA Portal.
Buffer Sizing: The Math Behind the Error
Modbus holding registers are 16-bit values. One Modbus register = 2 bytes = one WORD in the S7-1500 memory model. Every read or write job of N registers requires a buffer of 2N bytes at both sides of the connection.
Client-Side Buffer (MB_DATA_PTR)
The MB_DATA_PTR input on MB_CLIENT is a VARIANT pointer to a memory area that holds the data being read into (FC 03 / FC 04) or written from (FC 06 / FC 16). The pointed area must be at least MB_DATA_LEN bytes long. MB_DATA_LEN is specified in bytes, not registers — a common source of error.
Server-Side Buffer (MB_HOLD_REG)
When the server is an MB_SERVER block running on another S7-1500, the MB_HOLD_REG VARIANT points to the holding-register area. The number of registers served is determined by the buffer size in bytes divided by 2. The MB_HOLD_REG buffer starts at register number HR_Start_Offset (default 0). The first register exposed to the wire is therefore address HR_Start_Offset, not 0, when HR_Start_Offset > 0.
Worked Example
Configuration: client requests FC 03 (Read Holding Registers), start address 0, quantity 10. HR_Start_Offset at the server = 0. Default S7-1500 setup.
Server MB_HOLD_REG buffer ≥ 2 × (0 + 10 − 0) = 20 bytes
Client MB_DATA_PTR buffer ≥ 2 × 10 = 20 bytes
MB_DATA_LEN = 20
If the same client later requests start address 90, quantity 20 (covering registers 90..109), the server must hold at least 220 bytes of MB_HOLD_REG or HR_Start_Offset must be raised to 90 and the buffer must hold 40 bytes for the same wire range — but the wire-level addressing model differs in that case.
General Formula
Server buffer bytes ≥ 2 × (StartAddress + Quantity − HR_Start_Offset)
Client buffer bytes ≥ 2 × Quantity
Step-by-Step Resolution
Step 1 — Confirm the connection layer is healthy
- Open TIA Portal and connect online to the CPU 1513-1 PN.
- Open the watch table for the MB_CLIENT instance DB.
- Add the following tags to the watch table:
MB_CLIENT_DB.STATUSMB_CLIENT_DB.DONEMB_CLIENT_DB.ERRORMB_CLIENT_DB.CONNECT_IDMB_CLIENT_DB.IP_PORT
- Monitor over 30 seconds. If STATUS is 7004 only and never goes to 0000 even momentarily, the REQ trigger is the problem (skip to Step 7).
Step 2 — Inspect MB_DATA_PTR
- Open the MB_CLIENT instance DB in the project.
- Right-click
MB_DATA_PTR→ Go to referenced tag. - Confirm the target is a global data block (DB) or M area, not a local or temporary tag (MB_DATA_PTR must persist between calls).
- Confirm the target DB has Standard access (non-optimized) for legacy library versions, or Optimized if your library is V3.0+ and the documentation explicitly states optimized DB support.
- Confirm the data type is
ARRAY[..] OF WORDorARRAY[..] OF INT(UINT) for holding-register access, orARRAY[..] OF BOOLfor coil access (FC 01/05/15).
Step 3 — Match MB_DATA_LEN to the request
- Compute
MB_DATA_LEN = 2 × Quantity_of_Registers. - Verify the destination buffer is at least that long.
- If you are using a structured DB tag (e.g., a UDT), the block offsets are calculated by the compiler; do not declare MB_DATA_LEN based on the logical count of fields — declare it based on the physical byte width the request requires.
Step 4 — Verify the server-side MB_HOLD_REG area
- If the server is a second S7-1500, open its MB_SERVER instance DB.
- Check
MB_HOLD_REG— confirm the pointed area is large enough to cover the highest register the client will request. - Check
HR_Start_Offset— if it is 0 (default), the first wire address is register 0. If it is 100, register 100 is the first wire address. Mismatches here produce 8383. - Check
MB_SERVER_DB.CONNECT_ID— the connection ID at the server must match the client's connect ID for the same TCP connection if the same S7-1500 is also running the client (loopback tests).
Step 5 — Configure MODSIM32 correctly
- Open MODSIM32 → File → New → select 03: Holding Register (4xxxx).
- Set Address = 1 (MODSIM is 1-based; the first holding register on the wire is address 0).
- Set Length = 100 (or however many registers you want exposed).
- Confirm the server is connected in the status bar — MODSIM listens on TCP/502 by default.
- If the client requests registers 0..9 and MODSIM is configured for address 1..10, the wire match is correct. If the client requests 0..15 and MODSIM is 1..10, expect 8383 on registers 10..15.
Step 6 — Re-test and observe
- Download the corrected project to the CPU.
- Cold restart the CPU if requested by TIA Portal.
- Watch the STATUS word over several job cycles. You should now observe the following sequence per cycle:
- REQ rising edge → STATUS = 16#7005 (job executing)
- Job complete → STATUS = 16#0000, DONE = TRUE
- Between jobs → STATUS = 16#7004
- No 8383 should appear.
Step 7 — Fix the REQ trigger if STATUS is permanently 7004
- Open OB1 (or the cyclic OB calling MB_CLIENT).
- Confirm REQ is being driven by a rising-edge contact (a positive edge of a clock bit, a counter, or a state transition) — not a level-held TRUE.
- Typical pattern:
REQ := "Clock_1Hz" AND "Clock_1Hz_edge";using an edge memory bit (e.g.,CLK_1HZ_PEfrom a 1-Hz system clock). - A level-held REQ causes MB_CLIENT to fire one job at the rising edge only; subsequent calls with REQ=TRUE do not retrigger the job. A missing edge produces 7004 forever.
Diagnostic Flow (SVG)
Verification Checklist
| Item | Expected | How to Verify |
|---|---|---|
| STATUS at idle | 16#7004 | Watch table when REQ is FALSE |
| STATUS during job | 16#7005 | Watch table during REQ=TRUE |
| STATUS on success | 16#0000 with DONE=TRUE | Watch table on job completion |
| STATUS on buffer error | 16#8383 with ERROR=TRUE | Watch table — should be absent after fix |
| Client MB_DATA_PTR length | ≥ MB_DATA_LEN bytes | Cross-check DB declaration |
| Server MB_HOLD_REG length | ≥ 2 × (max register + 1 − HR_Start_Offset) | Cross-check server DB |
| MODSIM address window | Covers full requested range | MODSIM → register definition |
| HR_Start_Offset | Matches client request base | Instance DB static value |
| REQ trigger | Rising edge, not level | OB1 logic review |
| Library version | V3.x for S7-1500 FW V2.0+; V4.0+ for FW V3.0+ | TIA Portal → Library information |
| CPU firmware | ≥ V1.1 for CPU 1513-1 PN | Online → Diagnostics → CPU information |
| Open TCP connection | Visible in Netstat or netanalyzer | CPU Web Server → Connections / Wireshark |
Function Code Reference for MB_CLIENT / MB_SERVER
| FC | Function | MB_MODE | Buffer Type | Unit on the Wire |
|---|---|---|---|---|
| 01 | Read Coils | 0 (read) | BOOL array (packed) | 1 bit = 1 coil |
| 02 | Read Discrete Inputs | 0 (read) | BOOL array (packed) | 1 bit = 1 input |
| 03 | Read Holding Registers | 0 (read) | WORD / INT / UINT array | 1 register = 2 bytes |
| 04 | Read Input Registers | 0 (read) | WORD / INT / UINT array | 1 register = 2 bytes |
| 05 | Write Single Coil | 1 (write) | BOOL | 1 bit = 1 coil |
| 06 | Write Single Register | 1 (write) | WORD / INT / UINT | 1 register = 2 bytes |
| 15 | Write Multiple Coils | 1 (write) | BOOL array (packed) | 1 bit = 1 coil |
| 16 | Write Multiple Registers | 1 (write) | WORD / INT / UINT array | 1 register = 2 bytes |
MB_CLIENT vs. MB_SERVER Connection Parameters
Both blocks share a similar parameter model. The S7-1500 client configuration in TIA Portal typically uses the following inputs:
-
REQ(BOOL) — rising edge triggers a job. -
DISCONNECT(BOOL) — rising edge closes the TCP connection cleanly. -
CONNECT_ID(UINT) — unique connection identifier per active MB_CLIENT/MB_SERVER pair. Must be unique across the project. -
IP_OCTET_1..4(BYTE) — IPv4 octets of the server. -
IP_PORT(UINT) — TCP port; 502 is the standard Modbus port. -
MB_MODE(USINT) — 0 = read, 1 = write. -
MB_DATA_ADDR(UINT) — start address of the Modbus register/coil. -
MB_DATA_LEN(UINT) — length in bytes. -
MB_DATA_PTR(VARIANT) — pointer to the local data area. -
DONE,BUSY,ERROR,STATUS— outputs.
The MB_SERVER block on the server side adds:
-
MB_HOLD_REG(VARIANT) — pointer to the holding-register DB. -
HR_Start_Offset(UINT, static) — first register number on the wire; default 0.
Library and Firmware Compatibility
The MB_CLIENT/MB_SERVER blocks are not part of the S7-1500 firmware — they are library functions installed in the TIA Portal project from the Siemens MODBUS TCP library. The library version must be compatible with the CPU firmware generation.
| CPU Firmware | Compatible Library | Notes |
|---|---|---|
| V1.1 (CPU 1513-1 PN, original) | MODBUS TCP V1.x / V2.x | Legacy; supports S7-1500 base functions |
| V2.0 – V2.9 | MODBUS TCP V3.x | Recommended; optimized DB support, more diagnostics |
| V3.0 (current as of 2024–2025) | MODBUS TCP V4.0+ | Adds S7-1200 G2 support, extended error codes |
When upgrading a CPU 1513-1 PN from V1.1 to V2.x or V3.x in TIA Portal, also update the MODBUS TCP library to a compatible version. The TIA Portal library manager will warn you about mismatches at compile time.
Advanced Troubleshooting
Wireshark / Tcpdump Confirmation
To rule out any ambiguity between "connection works but data fails" and "connection itself is dropping," capture traffic on the CPU's PROFINET X1 port (port-mirrored on the switch). The expected traffic for a successful FC 03 request is:
Client → Server: Tx (MBAP header: TxID, ProtID=0, Length=6, UnitID=1)
PDU: FC=03, StartAddr=0000, Quantity=000A
Server → Client: Rx (MBAP header echoes TxID, ProtID=0, Length, UnitID=1)
PDU: FC=03, ByteCount=14, Data[14 bytes]
If the server returns exception code 02 (ILLEGAL_DATA_ADDRESS) — MB exception code 02 in the PDU — the server is telling the client the requested address is out of range. MB_CLIENT translates that into STATUS 16#8383. If the server returns exception code 03 (ILLEGAL_DATA_VALUE), the issue is the quantity or sub-function encoding.
Using the CPU Web Server for Live Status
Enable the CPU's Web Server (TIA Portal → CPU Properties → Web Server). Under Diagnostics → Connection you can see every open Modbus TCP connection, the partner IP/port, the connection state, and the number of bytes sent/received. Use this to confirm the MB_CLIENT socket is in state ESTABLISHED and not cycling through SYN/SYN-ACK/RST.
Loopback Test (Client and Server on the Same CPU)
For a quick sanity check, run an MB_CLIENT and MB_SERVER on the same CPU 1513-1 PN. Use:
- Client IP = 127.0.0.1 (loopback) or 192.168.0.10 (own IP)
- Different CONNECT_ID values for client and server
- Different IP_PORT values if both are set, or use the same 502 with distinct CONNECT_IDs
A working loopback proves the library, project compilation, and CPU are sound; the failure on the external MODSIM connection then narrows down to network/firewall/MODSIM address setup.
Common Pitfalls Field Notes
- HR_Start_Offset of 1 confusion. A common MODSIM setup is "Address = 1, Length = 10". The wire-level start is register 0 because MODSIM is 1-based and the first register is wire-register 0. Setting HR_Start_Offset = 1 on the server would shift the wire base to register 1 and would mismatch a client that requests register 0.
- MB_DATA_LEN off-by-one. Requesting quantity 10 with MB_DATA_LEN = 10 instead of 20. Fix: MB_DATA_LEN is always in bytes for register-based functions.
- MB_DATA_PTR on an optimized DB with library V1.x. The legacy library does not support optimized DB access. Either disable optimized access on the DB, or upgrade the library.
- REQ driven by a level instead of an edge. MB_CLIENT triggers one job per REQ rising edge. A level-held REQ produces 7004 forever.
- Watching STATUS only at one scan. 7004 and 8383 alternate between job cycles; sample STATUS at high frequency (every 100 ms) to see the pattern.
- Not using HR_Start_Offset. When porting an old STEP 7 V5.5 Modbus project, engineers sometimes forget the offset, and the wire registers appear to be shifted.
- Firewall blocking TCP/502. Windows Firewall on the PC running MODSIM frequently blocks inbound TCP/502. Add an inbound rule allowing port 502 or disable the firewall temporarily to confirm.
- Multiple CPU firmware upgrades without re-importing the library. After a firmware upgrade the TIA Portal project may still reference the old library version, producing sporadic 80B1 / 80C1 errors mixed with the 8383 pattern.
Parameter Cross-Reference Table
| Input | Data Type | Meaning | Common Mistake |
|---|---|---|---|
| REQ | BOOL | Rising edge starts a job | Held TRUE → no retrigger |
| CONNECT_ID | UINT | Unique connection identifier | Duplicate with MB_SERVER or another client |
| IP_OCTET_1..4 | BYTE | Server IPv4 address | Swapped octets, wrong subnet |
| IP_PORT | UINT | TCP port (502 standard) | Server on non-default port without IP_PORT update |
| MB_MODE | USINT | 0 = read, 1 = write | 0/1 swapped → 8383 on read attempt |
| MB_DATA_ADDR | UINT | First register / coil number | 1-based vs 0-based confusion |
| MB_DATA_LEN | UINT | Length in bytes | Set to register count instead of byte count |
| MB_DATA_PTR | VARIANT | Pointer to local buffer | Points to local/temp area; wrong DB length |
Related Status Codes You May Also See
| Code (hex) | Meaning | Likely Fix |
|---|---|---|
| 16#0000 | Job complete, no error | No action; DONE = TRUE |
| 16#7000 | No job active, no connection | First call; wait for connection |
| 16#7001 | First call, establishing connection | Wait for connection to complete |
| 16#7002 | Connection established, waiting for job | Trigger REQ |
| 16#7003 | Connection being closed | Wait for closure |
| 16#7004 | Connection established and monitored | Idle; expected between jobs |
| 16#7005 | Job executing | Wait for completion |
| 16#80C1 | Connection ID in use | Change CONNECT_ID; ensure uniqueness |
| 16#80C2 | Resource problem (no free connection) | Reduce concurrent connections; check CPU max |
| 16#80C3 | Connection broken / partner not reachable | Check IP, port, firewall, network |
| 16#8383 | Address out of MB_DATA_PTR / MB_HOLD_REG range | Increase buffer or reduce quantity |
FAQ
Is S7-1500 Modbus TCP status 7004 a fault?
No. W#16#7004 means the TCP connection is established and being monitored but no job is currently active. It is the idle status between Modbus requests and is normal.
What does 8383 mean on MB_CLIENT?
W#16#8383 indicates the client tried to read or write outside the address range of the MB_DATA_PTR buffer (client side) or the MB_HOLD_REG buffer (server side). Increase the buffer size, reduce the number of registers requested, or align the HR_Start_Offset.
How many bytes does one Modbus register occupy?
One Modbus holding register occupies 2 bytes (one WORD). A request for 10 registers requires a buffer of 20 bytes at both the client MB_DATA_PTR and the server MB_HOLD_REG. MB_DATA_LEN is specified in bytes, not registers.
What is HR_Start_Offset in MB_SERVER?
HR_Start_Offset is the parameter in the MB_SERVER instance DB that defines the register number where the MB_HOLD_REG buffer starts on the wire. The default is 0. If set to 100, wire address 0 maps to byte offset 200 inside the buffer, and the first register exposed to the client is 100.
Which Modbus TCP library version supports CPU 1513-1 PN V1.1?
CPU 1513-1 PN at firmware V1.1 requires a MODBUS TCP library version compatible with the V1.x firmware generation. For current diagnostics and optimized DB support, upgrade the CPU firmware to V2.x or later and use library V3.x or newer from the Siemens Industry Online Support (entry 109769202). V4.0+ libraries are required for S7-1500 firmware V3.0+ and S7-1200 G2.
My REQ is held TRUE but the job never repeats. Why?
MB_CLIENT triggers a job only on the rising edge of REQ. A level-held TRUE produces one job and then leaves the block in 7004. Use a clock-bit edge detector (e.g., 1 Hz from a system clock OB) or a counter edge to retrigger periodically.
MODSIM and the S7-1500 see the connection, but every read fails. What now?
Confirm MODSIM's holding-register definition (File → New → 03: Holding Register) covers the full register range the client requests. MODSIM is 1-based: address 1 corresponds to wire register 0. Mismatch on either end of the range is the typical root cause for an otherwise healthy connection that reports 8383.