Problem Overview
A SIMATIC S7-1200 (CPU 1211C / 1212C / 1214C / 1215C / 1217C) running both an open-user-communication (OUC) partner link implemented with TSEND_C / TRCV_C and a Modbus TCP server implemented with MB_SERVER (instruction version from the "MODBUS" library or the S7-1200 Modbus TCP V3.x / V4.x blocks) will drop the Modbus server with the STATUS word 16#80C3 the moment both blocks are downloaded. Removing TSEND_C / TRCV_C from the OB1 cycle makes the Modbus server run normally again, which rules out cabling, IP, port, and firewall causes. The fault is in the connection resource allocation, not in the wire.
This article documents the root cause, the meaning of the local error code, the exact parameter that must be changed, and the verification steps to confirm the fix on TIA Portal V15.1 through V18 (Firmware V4.2, V4.4, V4.5, V4.6).
Symptoms
-
MB_SERVERinstance DB showsSTATUS = 16#80C3on the first scan after download. -
MB_SERVER.DONEtoggles true for one cycle, butMB_SERVER.ERRORis also true andSTATUS = 16#80C3. - No third-party Modbus/TCP client can open a socket; a Wireshark trace shows only the server's SYN-ACK without a follow-up response after the Modbus request frame.
- TSEND_C reports a normal active connection (STATUS = 0) and exchanges process data without issue.
- Removing the TSEND_C and TRCV_C block calls — even with their instance DBs left in the project — clears the Modbus error. The fault returns as soon as the OUC blocks are re-inserted and re-downloaded.
Understanding Connection Resources on S7-1200
The CPU firmware allocates a fixed pool of connection endpoints at startup. Each open socket — PG, HMI, S7, OUC, Modbus, OPC UA, Profinet IO, and Send/Receive — consumes one endpoint. The pool is shared; assigning the same identifier (ID) to two blocks causes the firmware to map both instructions onto the same endpoint, which the run-time rejects as a duplicate resource claim.
| CPU | PG / OP / HMI | S7 connections | OUC + Modbus + open TCP/UDP | Total |
|---|---|---|---|---|
| 1211C | 3 + 8 | 8 | 8 | 19 |
| 1212C | 3 + 8 | 8 | 8 | 19 |
| 1214C | 3 + 8 | 8 | 8 | 19 |
| 1215C | 3 + 8 | 8 | 8 | 19 |
| 1217C | 3 + 8 | 8 | 8 | 19 |
Decoding Error Code 16#80C3
STATUS word 16#80C3 from MB_SERVER means "Connection resource already in use / no more connection resources available". The full error description in the S7-1200 Programmable Controller System Manual and in the MODBUS TCP library help is:
16#80C3 — The connection is already in use by another instance, or no further connection resources are available.
The two halves of the message are not the same fault:
| Sub-cause | Trigger | Resolution |
|---|---|---|
| ID collision | Another block (TSEND_C, TRCV_C, TCON, MB_CLIENT, MB_SERVER) declares the same ID on the same PROFINET interface of the same CPU. |
Reassign a unique ID to one of the blocks. |
| Resource exhaustion | All open-communication endpoints are used; the new block cannot get a fresh slot. | Reduce the number of simultaneously open OUC / Modbus connections or upgrade firmware to V4.4+ which raises the limit on 1215C/1217C. |
Because the original case shows the fault clears when the OUC blocks are removed and returns when they are added back, the problem is the first sub-cause: duplicate connection ID.
Why TSEND_C and MB_SERVER Collide
TSEND_C / TRCV_C are TIA Portal instructions from the "Extended Instructions → Communication → Open User Communication" group. The block uses the input CONNECT (a TCON_IP_v4 or TCON_IP_RFC1006 structure) which contains a ID field. The CPU indexes the open-communication endpoint by this ID. Refer to the official S7-1200 manual collection: TSEND_C and TRCV_C — Send and receive data using Ethernet.
MB_SERVER uses an instance DB in which the block stores its own ID. TIA Portal exposes this as the property "Connection ID" in the block's configuration interface. If the same numeric value is configured in TSEND_C.CONNECT.ID and in the MB_SERVER instance, the firmware refuses to bring up the second endpoint because that ID is already bound to the first connection description.
On a fresh project, TIA Portal defaults the new block's connection ID to 1. If you drop a TSEND_C first and accept the wizard defaults, then drop an MB_SERVER next, both can end up with ID 1 unless the wizard is finished manually and the ID is left at the default. Likewise, copying blocks from one program to another in the same CPU can re-use IDs that were valid in the source project but clash in the target.
Root Cause Confirmation
Open the online block interface of TSEND_C and MB_SERVER in TIA Portal and compare the IDs:
- Right-click the TSEND_C instance DB → "Open and monitor".
- Open the static
"id"tag under theCONNECTstructure. - Right-click the MB_SERVER instance DB → "Open and monitor".
- Read the
IDtag (or the configuration view's "Connection ID"). - If both show the same value, you have a duplicate.
Online, MB_SERVER.STATUS on the very first call after download will be 16#80C3 with no prior successful handshake, which confirms the collision rather than a runtime disconnect.
Solution: Reassign the Connection ID
The fix is to give each block a unique connection ID. Follow the procedure below for TIA Portal V15.1 or higher on a 1214C.
Prerequisites
- TIA Portal project that compiles cleanly with the original program.
- Online connection to the CPU (or at minimum an offline configuration session).
- A planning sheet of every connection ID currently in use (the Project tree → PLC → Connection resources view is the authoritative source).
Step-by-Step
- Inventory current IDs. In the project tree, expand the CPU node, open "Devices & networks", and open the "Connections" editor. Every configured connection (S7, TCP, ISO-on-TCP, Modbus, UDP, etc.) is listed with its local ID. Note which IDs are free.
- Pick a free ID for MB_SERVER. A typical layout is: TSEND_C = 1, MB_SERVER = 2, TCON → 3, etc. Avoid IDs in the range 200..255 because older firmware versions reserved some of these for system services.
- Open the MB_SERVER instance DB. In the project tree, navigate to Program blocks → System blocks → MB_SERVER_DB (or whatever you named it). Right-click → "Properties".
-
Change the Connection ID. In the Properties → Connection tab, the field "Connection ID" is at the top. Replace the current value with the free ID chosen in step 2. Click OK. The change is written into the instance DB's static
IDtag. - Recompile. Right-click the CPU → "Compile → Software (rebuild all)". Resolve any compile errors. A duplicate ID will not produce a compile error; the firmware is the only authority that detects the clash.
- Download. Use "Download to device → Software (only)" with the option "Consistent download of all blocks" disabled — there is no need to stop the CPU because the change is to a single instance DB initial value.
-
Verify online. Go online and monitor MB_SERVER. STATUS should now be
16#0000on the first call (or, more precisely, the function returns DONE = TRUE and ERROR = FALSE with STATUS = 0). The third-party Modbus client should be able to open a TCP connection on port 502 and read/write the configured data areas.
Verification and Diagnostics
After the change, run the following verification matrix.
| Check | How | Expected |
|---|---|---|
| MB_SERVER first-call STATUS | Online watch table, instance DB open and monitor | 16#0000 |
| MB_SERVER.ERROR | Same | FALSE |
| TSEND_C.STATUS | Same on TSEND_C instance DB | 0 (busy = FALSE) after first data exchange |
| Modbus client polling | Modbus Poll / external tool | 200 OK on read holding/input registers |
| Connection list in CPU | Online & Diagnostics → Connections | One TCP server entry with port 502 plus the TSEND_C partner entry |
| Wireshark | Capture on the LAN segment | SYN/SYN-ACK/ACK on port 502, then Modbus request/response |
Add a small online watch table that contains the four tags below to catch a future re-introduction of the same defect:
// Watch table "Modbus_OUC_diag"
"MB_SERVER_DB".STATUS // DWORD
"MB_SERVER_DB".ERROR // BOOL
"TSEND_C_DB".STATUS // DWORD
"TSEND_C_DB".BUSY // BOOL
A non-zero STATUS on either block accompanied by ERROR = TRUE is a starting point for re-diagnosing the conflict. A useful cross-check on TIA Portal V16 and higher is the "Online → Connectivity" view which lists every open endpoint with its ID, partner IP, partner port, local port, and idle time. Confirm that MB_SERVER's ID is unique and bound to local port 502.
Connection ID Planning Best Practice
For projects that will grow, define a numbering scheme up front and store it in a project README.
| Range | Purpose | Example |
|---|---|---|
| 1..9 | OUC partner links (TCP/ISO-on-TCP) to known PLCs | TSEND_C 1214C-A → 1214C-B: ID 1 |
| 10..19 | OUC partner links to HMI / SCADA | TSEND_C to WinCC RT: ID 10 |
| 20..29 | Modbus TCP server / Modbus TCP client | MB_SERVER: ID 20 |
| 30..39 | OPC UA server (V4.4+) | OPC_UA_SERVER: ID 30 |
| 40..49 | Reserved for future expansion | — |
| 200..254 | Do not use — reserved by system services on some firmware versions | — |
| 255 | Reserved by firmware (broadcast / internal) | — |
Other rules that prevent the 80C3 condition:
- Never copy a block instance from one CPU to another without inspecting the ID — the wizard does not auto-renumber.
- Keep one CPU = one ID range. If a project contains two CPUs that talk to each other, the local ID and the partner ID are independent; only the local ID must be unique within its own CPU.
- Prefer the V4.4+ Modbus TCP V3.x library; the older V2.x library only supports one server endpoint per ID but the ID-allocation rules are identical.
- Document the port for every open endpoint. Modbus TCP defaults to 502; if you change it, set the same port in the third-party client and check the CPU's local firewall rules in the Protection & Security → Connection mechanisms view.
Firmware-Specific Notes
| Firmware | Behaviour on duplicate ID | Notes |
|---|---|---|
| V4.0 | 80C3 on the second block, no compile warning | 6-endpoint OUC limit |
| V4.2 | Same | 8-endpoint OUC limit |
| V4.4 | Same — bugfix added for SSL and OPC UA but not for legacy ID handling | 8-endpoint limit; OPC UA on 1215C/1217C only |
| V4.5 / V4.6 | Same | Same 8-endpoint limit; verify with Online → Connectivity |
The diagnostic is uniform across firmware — the only variable is the size of the open-communication pool. If a project uses all 8 OUC endpoints and then adds a 9th block with a unique ID, it will still receive 16#80C3 on a different sub-cause (resource exhaustion). In that situation, the only fixes are (a) consolidate connections, (b) move the Modbus server onto a separate CPU acting as a gateway, or (c) on 1215C/1217C, switch to firmware V4.4+ and add an OPC UA server in parallel if the third-party supports it.
Modbus Server Configuration Reference
For the CPU 1214C in the original case, a minimal working MB_SERVER setup is:
-
MODE=0(TCP server) -
DATA_PTR= pointer to a global DB ofARRAY [0..199] OF WORDfor holding registers -
ID= unique connection ID (e.g.20per the scheme above) -
IP_PORT=502(default Modbus TCP port) -
MB_HOLD_REG= instance of the holding-register data block
The block sits in OB1 (or a cyclic OB of priority 1) and runs once per cycle. MB_SERVER itself only updates its instance DB on a client request; the rest of the cycle the function call is effectively a no-op aside from state machine maintenance.
For the legacy and current variants of TSEND_C / TRCV_C, see the Siemens manual: Legacy TSEND_C and TRCV_C and the corresponding TSEND_C / TRCV_C instructions page.
Troubleshooting Matrix for Related Faults
| STATUS | Block | Meaning | First action |
|---|---|---|---|
| 16#80C3 | MB_SERVER / TCON / TSEND_C | ID collision or no resources | Verify ID is unique; check open-comm pool usage |
| 16#80C4 | TSEND_C / TRCV_C | Temporary communications error, partner not reachable | Verify partner IP, subnet, partner TSEND_C ID |
| 16#80C7 | TSEND_C / TRCV_C | TCP connection has been terminated by the partner | Check partner CPU state, partner block |
| 16#80B0 | TSEND_C / TRCV_C | Cannot establish connection; TCP/IP stack error | Verify IP, subnet mask, gateway on the CPU's PROFINET interface |
| 16#8186 | MB_SERVER | Wrong DATA_PTR or instance DB version | Recompile, re-download instance DB |
| 16#80A1 | MB_SERVER | Port 502 is in use by another server on the same CPU | Stop the other server or change the port |
Field-Proven Caveats
- The connection ID is local to the CPU. Two CPUs in the same project can each have an ID 1 — that is not a conflict. The conflict is when two blocks on the same CPU share an ID.
- Editing an MB_SERVER's instance DB "ID" tag online is a one-shot fix only — the next download from TIA Portal will overwrite your online change with whatever the offline value is. Always change the offline value and re-download.
- Do not assume that a green TIA Portal compile bar means the IDs are OK. The compiler checks data types and link consistency; duplicate IDs are a runtime concern.
- If the Modbus server is dropped because of a duplicate ID, the connection-resource manager will not "heal" — the fault is permanent until a download with corrected IDs is performed. A power cycle does not change IDs.
- On S7-1200 with firmware V4.0 / V4.1, the open-communication pool is 6 endpoints. Two OUC + one Modbus server + one OPC UA (if present) = four endpoints, which fits. Two OUC + one Modbus + one OPC UA + one extra TCON = five, still fine. Six blocks on the same CPU is the practical ceiling on those firmware versions.
- MB_SERVER does not distinguish multiple Modbus clients in its STATUS; if the fault is "no resources" rather than "duplicate ID", every client connecting will be refused and the single STATUS will read 16#80C3 — the way to tell the two sub-causes apart is to remove the suspected colliding block and observe whether STATUS clears.
What does STATUS 16#80C3 mean on MB_SERVER in an S7-1200?
It means the connection is already in use by another instance on the same CPU, or no further connection resources are available. On a 1214C the open-communication pool is 8 endpoints on firmware V4.2 and above. The most common cause on a single-CPU project is a duplicate connection ID between MB_SERVER and a TSEND_C / TRCV_C / TCON block.
Can TSEND_C and MB_SERVER run on the same S7-1200 CPU at the same time?
Yes. They share the same open-communication pool but each block is allowed one unique ID. Configure TSEND_C with ID 1 and MB_SERVER with ID 2 (or any two unique values) and both blocks will run concurrently, limited only by the 8-endpoint pool ceiling.
Where do I change the connection ID of MB_SERVER in TIA Portal?
Open the MB_SERVER instance DB, choose Properties, and edit the "Connection ID" field. Recompile, download the software, and verify online. The change is written to the static "ID" tag of the instance DB.
Does the connection ID have to be unique across both CPUs in a partner link?
No. The connection ID is local. A 1214C-A and a 1214C-B can each use ID 1 for the same partner link — the local ID and the partner ID are independent fields. The conflict is only when two blocks on the same CPU share an ID.
How do I confirm the fix without a third-party Modbus client?
Open the MB_SERVER instance DB online, monitor STATUS, and use a Wireshark capture on the LAN to confirm a SYN-ACK is returned on port 502 followed by a Modbus response to a request such as FC03 (Read Holding Registers) against a known offset. If the firmware refuses the connection, you will see only a SYN/RST exchange.