Resolving TIA Portal Modbus TCP Error 16#80BB: ActiveEstablished

David Krause13 min read
ModbusSiemensTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Error Overview

Error code 16#80BB returned on the STATUS output of the Siemens MB_CLIENT instruction in TIA Portal (STEP 7 V16/V17/V18/V19) indicates "Invalid value at ActiveEstablished parameter (identifier for the type of connection establishment)". The fault originates from the underlying TCON connection block, not from the Modbus protocol layer itself. For an S7-1200 (firmware 4.4 or later) or S7-1500 CPU acting as a Modbus TCP client, the connection establishment direction in the TCON configuration must be set to active, which corresponds to ActiveEstablished = TRUE in the TCON_IP_V4 data block. When the value remains at the default FALSE, the client opens a passive socket, the server never sees a SYN request, and MB_CLIENT reports W#16#80BB on every call.

This is one of the most common first-time failures when learning TIA Portal Modbus programming with PLCSIM Advanced and a third-party Modbus master/slave simulator such as Modbus Poll. The fix is a single bit in the connection description; verification is one cycle of MB_CLIENT after a recompile and download.

Root Cause Analysis

The MB_CLIENT instruction is a wrapper around three lower-level Open User Communications (OUC) blocks: TCON for connection management, TSEND for Modbus request frames, and TRCV for Modbus response frames. The TIA Portal online help for MB_CLIENT shows the STATUS mapping back to the underlying instruction, but the value W#16#80BB is not generated by MB_CLIENT itself; it is propagated from the TCON status that MB_CLIENT triggers internally on its first call.

The TCON block accepts a system data type TCON_IP_V4 that contains, among other fields:

Parameter Data Type Meaning
InterfaceId HW_ANY Hardware identifier of the PROFINET interface
ID CONN_OUC Connection reference (1..4095, unique per CPU)
ConnectionType USINT 17 = TCP/IP (used for Modbus TCP)
ActiveEstablished BOOL TRUE = active (client), FALSE = passive (server)
RemoteAddress IP_V4 IP address and port of the partner
LocalPort UINT Local port (0 = assign automatically)
RemotePort UINT Remote port (502 for Modbus TCP)

When ActiveEstablished is FALSE in a configuration that is wired to MB_CLIENT, the OUC stack returns STATUS = 16#80BB on the very first call where REQ is set. The error persists until either the parameter is flipped to TRUE or the project is recompiled and downloaded.

Critical: The 16#80BB error is also reported if ActiveEstablished = TRUE is set on a connection that is consumed by a server-side instruction (e.g. MB_SERVER, TRCV_C). The parameter is direction-sensitive; mismatch in either direction produces the same status code.

Modbus TCP STATUS Code Reference

The table below lists the STATUS values most frequently observed on MB_CLIENT in TIA Portal V16/V17/V18/V19. Codes in the 7xxx range are non-error progress states; codes in the 8xxx range are actual errors requiring corrective action. Reference: Siemens FAQ: Status evaluation of system blocks.

STATUS (Hex) Source Meaning Action
16#0000 MB_CLIENT No error, instruction idle None
16#7000 MB_CLIENT No job in progress, REQ = 0 None
16#7001 MB_CLIENT First call, job started None
16#7002 MB_CLIENT Connection establishment in progress Wait, poll DONE/BUSY/ERROR
16#7003 MB_CLIENT Connection established, awaiting response None
16#7004 MB_CLIENT Data being sent/received None
16#7005 MB_CLIENT Receive complete, data available None
16#80BB TCON Invalid ActiveEstablished parameter Set TRUE for client
16#80C0 TCON Connection ID already in use Use unique ID per CPU
16#80C1 TCON Maximum number of connections exceeded Reduce connection count
16#80C3 TCON All connection resources in use Free a connection
16#80C4 TCON Partner IP address invalid Verify IP in TCON_IP_V4
16#80C8 TSEND/TRCV No connection resource available Check CPU OUC limits
16#80CE TSEND/TRCV Partner refused connection (RST) Verify server, port 502
16#80D2 TSEND/TRCV Partner closed connection Check server software
16#8181 MB_CLIENT Modbus exception code 01 (illegal function) Verify FC number
16#8182 MB_CLIENT Modbus exception code 02 (illegal address) Verify Modbus address
16#8183 MB_CLIENT Modbus exception code 03 (illegal data value) Verify quantity/coils
16#818C MB_CLIENT Modbus exception code 0C (gateway path) Verify gateway router
16#8380 MB_CLIENT Parameter assignment error (MODE/MB_DB) Inspect MB_DB structure

Why STATUS 16#7002 Is Not an Error

After fixing the ActiveEstablished parameter to TRUE, engineers typically observe that STATUS settles on 16#7002 and never returns to 16#80BB. The natural assumption is that the new code is still wrong. It is not.

W#16#7002 is the normal OUC standby state for an active TCP connection that has been established and is idle. MB_CLIENT reports 16#7002 whenever:

  • The TCP socket is open and the connection is healthy.
  • No Modbus request is in flight (no rising edge on REQ).
  • No data is being read from the response buffer.

The relevant signals are therefore DONE, BUSY and ERROR, not the steady-state STATUS. A persistent 16#7002 with ERROR = FALSE is a healthy Modbus TCP client waiting for the next transaction.

Tip: Do not evaluate STATUS inside the same cyclic OB in which you call MB_CLIENT. The instruction refreshes STATUS on every call, so transient values (such as 16#7001, 16#7003) are overwritten before you can read them. Latch STATUS into a static tag on the rising edge of ERROR or DONE; this is the only reliable way to capture failure modes in TIA Portal.

The ActiveEstablished Parameter in Detail

The ActiveEstablished bit is a single BOOL that decides which side of the TCP three-way handshake initiates the SYN packet:

  • TRUE (active, client): The CPU sends the first SYN toward the configured remote IP/port. This is the correct setting for a Modbus TCP client polling a Modbus TCP server (PLC, drive, instrument, third-party simulator).
  • FALSE (passive, server): The CPU listens for an incoming SYN on the configured local port. This is the correct setting for MB_SERVER or any OUC server-side block.

In TIA Portal, the parameter is exposed in two places:

  1. Project tree → PLC → Communication → Connection table when configuring a programmed connection. The "Establishment" column shows Active/Passive.
  2. The TCON_IP_V4 instance DB created in the program blocks. The bit is accessible under MyConn.ActiveEstablished.

Either entry point must reflect the same value. If you change one and not the other, recompilation will overwrite the block and the inconsistency returns. For a project-side connection table, edit the connection properties, change "Establishment" to Active, save, recompile, and download. For a programmatic TCON_IP_V4 DB, open the DB, edit the bit, and download just the block.

MB_CLIENT Configuration: Required Inputs

The S7-1200/1500 MB_CLIENT instruction requires the following input wiring to operate correctly. The values shown are typical for a bench test against Modbus Poll on a workstation IP of 192.168.0.50.

Input Data Type Example Value Notes
REQ BOOL Trigger pulse Rising edge starts a Modbus transaction
DISCONNECT BOOL FALSE Rising edge tears down TCP connection
CONNECT_ID UINT 1 Must match the ID in TCON_IP_V4
MB_MODE USINT 0/1 0 = read, 1 = write
MB_DATA_ADDR UDINT 40001 Modbus address (1-based for FC03/06/16)
MB_DATA_LEN UINT 10 Number of registers/coils
MB_DATA_PTR VARIANT Data block Pointer to source/destination buffer
DONE BOOL Output TRUE for one cycle on success
BUSY BOOL Output TRUE while transaction is in progress
ERROR BOOL Output TRUE when STATUS contains an error
STATUS WORD Output See STATUS reference table above

For the S7-1500 firmware 2.9 onwards, the multi-instance form MB_CLIENT_DB is preferred over the older S7-1200 form. The two implementations are functionally identical for the purposes of error 16#80BB. The MB_DATA_PTR must point to a standard-access DB or to a tag of type BOOL/INT/REAL/WORD array. Pointing to an optimized (symbolic-only) tag triggers 16#8380.

Step-by-Step Resolution Procedure

  1. Open the TIA Portal project and navigate to Project tree → [CPU] → Program blocks.
  2. Locate the instance DB that holds the TCON_IP_V4 structure. It is typically named iParams, ConnectionData, or any user-defined name assigned during MB_CLIENT insertion.
  3. Double-click the DB to open it and locate the field ActiveEstablished.
  4. Change the value from FALSE to TRUE.
  5. Compile the project (Project → Compile → Software (rebuild all)).
  6. Download the program to the S7-PLCSIM Advanced instance (Online → Download to device).
  7. Place the CPU in RUN.
  8. Trigger a Modbus transaction by setting REQ for one cycle.
  9. Observe the STATUS output. It should now sit at 16#7002 with ERROR = FALSE between transactions, and flicker through 16#7001/16#7003/16#7004 during a transaction.
  10. Confirm that the connected Modbus server (Modbus Poll) reports the expected read or write.
Caution: If you are using a configured connection rather than a programmatic one (Connection table under "Devices & Networks"), the ActiveEstablished setting there must also be set to Active. Changing only the TCON_IP_V4 instance DB will not affect a project-side connection; they are independent records.

Latching the STATUS Output

Because STATUS is overwritten every scan, the following SCL pattern is required to capture transient errors for diagnostics. The block is called from the same OB (typically OB1) that calls MB_CLIENT, but executes its latch logic on a different scan than the call:

// SCL - Latch MB_CLIENT STATUS on error or done
IF "mb_client_instance".ERROR OR "mb_client_instance".DONE THEN
    "latched_status" := "mb_client_instance".STATUS;
    "latched_done"  := "mb_client_instance".DONE;
    "latched_error" := "mb_client_instance".ERROR;
END_IF;

// Reset only when next REQ starts
IF "req_edge" THEN
    "latched_status" := 16#0000;
    "latched_error" := FALSE;
END_IF;

You can also place a parallel HMI tag on latched_status and an evaluation FC that decodes the value to a human-readable string. The referenced Siemens FAQ 109755840 provides a status-to-text function that maps every value in the table above to a descriptive message.

PLCSIM Advanced Setup

PLCSIM Advanced is required for the S7-1500 and recommended for the S7-1200 (PLCSIM V15.1+ supports S7-1200 firmware 4.4). For Modbus TCP testing:

  1. Install PLCSIM Advanced and start the service (S7PlcSimX.exe -apiport=8888).
  2. Create a virtual Ethernet adapter. On Windows, use the Network adapter → Microsoft KM-TEST Loopback Adapter or a TAP-Windows adapter.
  3. Configure the virtual adapter with an IP in the same subnet as the Modbus server (e.g. 192.168.0.10/24).
  4. In the PLCSIM Advanced instance, bind the CPU's PROFINET interface to the virtual adapter.
  5. Start Modbus Poll on the workstation. Set Connection → Connect → TCP/IP → remote IP to the PLCSIM Advanced IP, remote port 502.
  6. Confirm with a PING from the workstation to the PLCSIM Advanced IP. If PING fails, the virtual adapter is not bridged correctly and no Modbus traffic will flow.
Important: PLCSIM (the classic version) does not support MB_CLIENT on S7-1500. You must use PLCSIM Advanced for S7-1500 Modbus TCP testing. The S7-1200 (FW 4.4+) is supported in both PLCSIM and PLCSIM Advanced.

Modbus Poll Configuration

Modbus Poll (from Witte Software) is a common Modbus master/slave simulator. When used as the server (slave) for an S7 PLC client:

  1. Launch Modbus Poll and choose Connection → Connect → Modbus TCP/IP.
  2. Set the local port to 502 (default Modbus TCP server port).
  3. Set the listening IP to 0.0.0.0 to accept connections on any interface, or the specific workstation IP.
  4. Define a register map: Setup → Read/Write Definition → Slave ID = 1, Function = 03 (Holding Register), Address = 1, Quantity = 10.
  5. Set the poll delay to 1000 ms to avoid saturating the simulator during a connection test.
  6. Click OK and confirm that the traffic light turns green when the S7 client connects.

If the S7 client shows STATUS = 16#7002 and ERROR = FALSE, but Modbus Poll shows no incoming connection, the issue is at the network layer, not the Modbus layer. Re-check firewall rules on Windows: port 502 must be allowed inbound on the workstation profile. Run netstat -an | findstr :502 from an elevated command prompt to confirm the server is listening.

Connection Resource Limits per CPU

Each S7 CPU has a fixed number of OUC connection resources. Exceeding this limit produces 16#80C1 or 16#80C3, which can be confused with 16#80BB if you are inspecting only the MB_CLIENT instance. Refer to the CPU manual for exact figures:

CPU Class Typical OUC Resource Limit Notes
S7-1200 (CPU 1211C..1215C) 8 connections Modbus TCP consumes 1 each for client/server
S7-1200 (CPU 1217C) 16 connections Higher-end compact
S7-1500 (CPU 1510/1511) 32 connections Entry-level modular
S7-1500 (CPU 1515/1516) 64 connections Mid-range
S7-1500 (CPU 1517/1518) 128 connections High-end modular
ET 200SP CPU Same as equivalent S7-1500 Distributed topology

Modbus Function Code Selection

MB_MODE and MB_DATA_ADDR together select the Modbus function code. Use the table below to map your application to the correct FC. Misconfiguration of FC triggers 16#8181 on the server side or silently fails on the client.

MB_MODE Modbus FC Description Address Range
0 FC 01 Read Coils 00001..09999
0 FC 02 Read Discrete Inputs 10001..19999
0 FC 03 Read Holding Registers 40001..49999
0 FC 04 Read Input Registers 30001..39999
1 FC 05 Write Single Coil 00001..09999
1 FC 06 Write Single Register 40001..49999
1 FC 15 Write Multiple Coils 00001..09999
1 FC 16 Write Multiple Registers 40001..49999

Wireshark Verification

To definitively prove the ActiveEstablished fix worked, capture a Modbus TCP session with Wireshark on the workstation interface:

  1. Start Wireshark on the loopback/TAP adapter. Use the capture filter tcp.port == 502 to limit noise.
  2. Trigger a transaction from the S7 client.
  3. Confirm the three-way handshake: SYN from PLCSIM IP, SYN-ACK from workstation, ACK from PLCSIM IP.
  4. Confirm the Modbus MBAP header: Transaction Identifier, Protocol Identifier = 0, Length, Unit Identifier.
  5. Confirm the function code in the request matches the configured MB_MODE + address range.

If the capture shows only TCP RST from the workstation to the PLCSIM IP, the server is refusing the connection. Check the Modbus Poll slave ID and listening port. If the capture shows no traffic at all, the ActiveEstablished fix did not take effect; re-verify the bit in the TCON_IP_V4 instance DB after recompile.

Verification Checklist

Before declaring the fault resolved, validate the following points:

Check Expected Result How to Verify
ActiveEstablished parameter TRUE in TCON_IP_V4 Open instance DB, read bit
Connection table (if used) Establishment = Active Devices & Networks view
MB_CLIENT STATUS idle 16#7002 Watch table, online
MB_CLIENT ERROR FALSE between transactions Watch table, online
MB_CLIENT DONE Pulse TRUE for one scan after successful transaction Trace or watch table
Modbus Poll Connection light green; values updating Modbus Poll display
Latched STATUS Returns to 16#0000 on next REQ HMI or watch table
Local port 502 reachable Telnet to workstation IP 502 succeeds telnet 192.168.0.50 502
Wireshark SYN from PLC, Modbus MBAP frame, response visible Wireshark capture on loopback

Common Related Errors and Their Fixes

If 16#80BB is replaced by a new error after the parameter fix, the most likely follow-up issues are:

  • 16#80C4 - Partner IP invalid: The IP in RemoteAddress is unreachable. Verify with PING from the PLCSIM Advanced instance.
  • 16#80CE - Partner refused: The remote server is not listening on port 502. Start Modbus Poll and confirm port 502 is open with netstat -an.
  • 16#80C0 - Connection ID in use: Another TCON block is using the same ID. Each connection in a CPU must have a unique ID.
  • 16#8380 - Parameter assignment: The MB_DATA_PTR variant points to a DB whose length is shorter than MB_DATA_LEN requires. Resize the DB or reduce the length.
  • 16#8181 - Illegal function: The Modbus server does not support the function code being requested. Verify FC mapping on the server side; many free Modbus Poll profiles disable FC 15/16 by default.

Frequently Asked Questions

What does Modbus TCP error 16#80BB mean in TIA Portal?

It means the ActiveEstablished parameter in the TCON connection description is set incorrectly. For a Modbus TCP client, the value must be TRUE (active connection establishment). Set it to FALSE only for server-side instructions such as MB_SERVER.

Is STATUS 16#7002 an error on MB_CLIENT?

No. 16#7002 is the normal standby status indicating the TCP connection is established and the client is idle. Real errors are flagged by ERROR = TRUE and produce values in the 8xxx range. Use the DONE/BUSY/ERROR outputs to determine transaction state, not the steady-state STATUS.

Why does the STATUS value change every scan in TIA Portal?

MB_CLIENT updates STATUS on every cyclic call. Transient values like 16#7001, 16#7003 or 16#7004 are visible for only a single scan. Latch the STATUS into a static tag on the rising edge of ERROR or DONE to capture persistent failure codes for diagnostics.

Does PLCSIM support MB_CLIENT on S7-1500?

No. The classic PLCSIM does not support MB_CLIENT on S7-1500 CPUs. You must use PLCSIM Advanced with a virtual Ethernet adapter and an external Modbus server such as Modbus Poll. The S7-1200 (firmware 4.4+) is supported in both PLCSIM and PLCSIM Advanced.

Can MB_CLIENT and MB_SERVER run on the same S7 CPU?

Yes. The CPU can host both a client and a server on separate connections. Each connection must have a unique CONNECT_ID and a unique TCON_IP_V4 instance. The client connection uses ActiveEstablished = TRUE; the server connection uses ActiveEstablished = FALSE. Mismatching the parameter on either side will re-trigger 16#80BB.

Back to blog