Troubleshooting TIA V16 MQTTClient Connection on PLCSIM Advanced

David Krause10 min read
SiemensTIA PortalTroubleshooting
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

Problem Statement

When commissioning a SIMATIC S7-1500 MQTT application in TIA Portal V16 against a physical CPU (for example, a 6ES7511-1AK02-0AB0 CPU 1511-1 PN), the Siemens MQTTClient library connects cleanly to a broker on the same subnet. After switching the project target from a real CPU to PLCSIM Advanced 3.0, the same instance DB starts, the STATUS word returns 16#0000 (no error at the block boundary), yet the TCP session to the broker never opens. No diagnostic buffer entry, no TLS alert, and no error code from MQTT_Client_Connect surfaces in the watch table.

This article documents the root cause path, the network architecture that PLCSIM Advanced 3.0 imposes, and the exact steps to bring the same MQTTClient code base online under a virtual S7-1500 instance without modifying the application logic.

PLCSIM Advanced 3.0 Network Architecture

PLCSIM Advanced 3.0 is not a classic soft-PLC. It runs as a Windows service and exposes a virtual Ethernet adapter (Siemens PLCSIM Virtual Ethernet Adapter, NDIS miniport) to the host. The instance DB executed inside the simulated CPU talks to the broker through this adapter rather than through the host's physical NIC. The implication is critical for MQTT:

  • Every TCP connection originates from the IP address assigned to the PLCSIM Virtual Ethernet Adapter, not from the host's primary IP.
  • The adapter is a separate Layer-2 segment. By default, traffic is NATted to the host's primary interface, but routing rules, Windows firewall profiles, and binding order all apply independently.
  • Multicast DNS, link-local IPv6, and certain TLS handshakes can be silently dropped on this adapter if the Windows network profile is set to Public.

Reference: Siemens Support entry 109773538 – SIMATIC S7-PLCSIM Advanced V3.0 function manual.

MQTTClient Library Identification

The library in question is the official Siemens "MQTT Client" library (entry ID 109748955 for TIA Portal V16 Update 6 and later). The relevant blocks are:

Block Type Function
MQTT_Client FB Encapsulates the MQTT 3.1.1 client state machine.
MQTT_Client_DB DB Instance DB; pass to MQTT_Client by reference.
MQTT_Connect FB Opens the TCP/TLS session and sends the CONNECT frame.
MQTT_Publish FB Publishes a topic payload.
MQTT_Subscribe FB Registers a topic filter and tracks incoming messages.
MQTT_Disconnect FB Graceful close (DISCONNECT control packet).

The library wraps TCON, TSEND, TRCV, and (for TLS) the OpenSSL-based TLS_Client function block from the same Siemens security library. Always confirm the library is the Siemens-published version and not a third-party redistribution: check Project > Libraries > Library overview and verify the publisher certificate in the library properties.

Root Cause Matrix

For an MQTTClient that connects to a real PLC but fails on PLCSIM Advanced 3.0 with no error code, work through the matrix in order:

# Likely Cause Symptom Quick Check
1 Broker IP is the host's primary IP; PLCSIM adapter cannot route to it TCON returns 16#7000 forever Ping the broker from a CMD running as Administrator using the PLCSIM adapter's source IP
2 Windows Firewall blocks the PLCSIM adapter on the chosen profile (Public/Private/Domain) TCP SYN sent, no SYN-ACK, no RST netsh advfirewall show allprofiles and check the rule "Siemens PLCSIM"
3 Broker is bound to 127.0.0.1 only Works on physical PLC (off-host), fails on PLCSIM (on-host) netstat -an | findstr 1883
4 TLS certificate CN/SAN does not include the broker hostname; OpenSSL handshake aborts silently inside the simulated CPU Plain TCP works, TLS does not; STATUS stays 16#0000 Connect with openssl s_client -connect <broker>:8883
5 PLCSIM instance is not in Run mode or CPU password is missing OB1 does not execute; STATUS never updates PLCSIM Advanced UI → instance → Run (F5)
6 PG/PC interface for S7ONLINE points to the wrong adapter Online watch works, but PLC-to-broker traffic never leaves the host TIA Portal → Options > Set PG/PC interface
7 Keep-alive mismatch; broker times out before CONNECT/CONNACK round-trip Broker log shows inbound connection then immediate close Set KeepAlive ≥ 60 s during commissioning

Verifying the PLCSIM Virtual Ethernet Adapter

Open an elevated PowerShell and confirm the adapter is present and enabled:

Get-NetAdapter | Where-Object {$_.Name -like "*PLCSIM*"} | Format-List Name,Status,LinkSpeed,ifIndex
Get-NetIPAddress -InterfaceAlias "Siemens PLCSIM Virtual Ethernet Adapter" | Format-List IPAddress,PrefixLength

Typical result on a default install:

  • Adapter name: Siemens PLCSIM Virtual Ethernet Adapter
  • Status: Up
  • IPv4: 192.168.1.100 / 24 (set during instance download)
  • Gateway: 192.168.1.1 (host-side bridge)

If the adapter is missing, the SIMATIC S7-PLCSIM Advanced Licensing Service and SIMATIC S7-PLCSIM Advanced services must both be running. Reinstall the NDIS driver shipped under %ProgramFiles%\Siemens\Automation\PLCSIMADV\Drivers if Windows has disabled it after a major update.

Routing the Broker Through the PLCSIM Adapter

Two topologies are common:

  1. Broker on the host — the broker (Mosquitto, HiveMQ CE, EMQX) binds to 0.0.0.0:1883 and the PLCSIM CPU must reach it. The PLCSIM Virtual Ethernet Adapter and the host's physical NIC share a default route through the host's TCP/IP stack, so the broker's primary IP is reachable. If the broker binds to 127.0.0.1 only, it is not reachable from PLCSIM. Change the bind_address in mosquitto.conf to 0.0.0.0 or to a non-loopback address.
  2. Broker on a different host — the PLCSIM adapter's gateway must be set to an IP that the host can route to. PLCSIM Advanced supports adding a default route at instance download time, but on Windows 10/11 the host firewall still controls the egress. Create a per-application rule: New-NetFirewallRule -DisplayName "PLCSIM MQTT" -Direction Outbound -Program "%ProgramFiles%\Siemens\Automation\PLCSIMADV\bin\PLCSIMAdv.exe" -Action Allow.

Step-by-Step Resolution

  1. Confirm the library version. In TIA Portal V16, open Libraries > Library overview, select the MQTT Client library, and check the version against the official entry. TIA V16 must use a library compiled for V16; libraries compiled for V17 SP1 will not load into a V16 project. The matching entry is Siemens entry 109748955 — "MQTT Client" for TIA Portal V16.
  2. Verify the CPU is in Run. In PLCSIM Advanced 3.0, the instance row must show a green Run indicator and the LED "RUN" must be solid. Press F5 if it is not. The CPU will not execute OB1 in Stop, so the MQTT_Client FB never gets a call.
  3. Set the PG/PC interface. In TIA Portal, Options > Set PG/PC interface > S7ONLINE (STEP 7) → TCP/IP → Siemens PLCSIM Virtual Ethernet Adapter. Online actions then route through the same adapter that the simulated CPU uses, which keeps the engineering and runtime paths consistent.
  4. Check the broker binding. On Windows, run netstat -ano | findstr :1883. The local address must be 0.0.0.0:1883 or the host's primary IP, not 127.0.0.1:1883. For Mosquitto, edit mosquitto.conf:
    listener 1883 0.0.0.0
    allow_anonymous true
    log_type all
    Restart the broker and confirm with the same netstat command.
  5. Open a manual TCP session from the PLCSIM context. In TIA Portal, add a small SCL routine in OB1 that copies the broker IP into a TCON parameter and call TCON with a 5-second timeout. Watch the DONE, BUSY, and ERROR/STATUS outputs. A STATUS of 16#80C4 confirms the adapter has a valid IP; 16#80A7 confirms a TCP timeout; 16#80AB confirms the host refused the connection.
  6. Disable the Windows Firewall for the PLCSIM profile as a test, then re-enable with a scoped rule:
    New-NetFirewallRule -DisplayName "MQTT 1883 outbound" `
      -Direction Outbound -RemotePort 1883 `
      -Protocol TCP -Action Allow -Profile Any
    The Siemens installer registers a rule set under the name "SIMATIC S7-PLCSIM Advanced" — verify it is enabled on the active profile.
  7. Configure TLS only after plain TCP works. Switch the MQTT_Client connection resource to TLS port 8883. Import the broker's CA certificate into the TIA project under Device > Security > Certificate manager. If the broker uses a self-signed certificate, the CN/SAN must match the hostname used in the MQTT_Client connection, not the IP. Use the hostname, e.g., mqtt.local, not 192.168.1.20.
  8. Increase the keep-alive and disable LWT during commissioning to remove the broker's CONNACK drop path. Set KeepAlive to T#60s and leave WillFlag = FALSE.
  9. Recompile and download the hardware configuration to the PLCSIM instance, then power-cycle the instance (right-click → Power off, then Power on). Power cycling is required when changing the IP of the virtual adapter, because a running instance keeps the old socket descriptors until the next cold start.
  10. Validate the end-to-end session with a subscriber on the host: mosquitto_sub -h 192.168.1.20 -p 1883 -t "plc/#" -v. Then trigger a publish from the CPU. A round-trip latency of < 50 ms confirms a healthy path.

Wiring the MQTTClient Block in SCL

A minimal, working MQTT_Client call that survives both a real CPU and PLCSIM Advanced 3.0 looks like this:

// OB1 - Cyclic main
"MQTT_Client_DB"(  // instance DB of MQTT_Client
    Connect      := "MQTT_Connect_DB",
    Publish      := "MQTT_Publish_DB",
    Subscribe    := "MQTT_Subscribe_DB",
    Disconnect   := "MQTT_Disconnect_DB",
    BrokerHost   := '192.168.1.20',      // broker IP, NOT 127.0.0.1
    BrokerPort   := 1883,
    ClientId     := 'S7_1500_01',
    KeepAlive    := T#60s,
    CleanSession := TRUE,
    Username     := '',
    Password     := '',
    UseTLS       := FALSE,
    Busy         => "statBusy",
    Error        => "statError",
    Status       => "statStatus",          // 16#0000 = no block error
    Connected    => "statConnected"
);
IF "statConnected" THEN
    "MQTT_Publish_DB"(Topic := 'plc/temperature', Payload := "tagTemperature");
END_IF;

The most common mistake is setting BrokerHost to 'localhost' or '127.0.0.1' while the simulated CPU is bound to the PLCSIM Virtual Ethernet Adapter. The TCP stack inside the CPU does not resolve localhost to the host loopback; it resolves it to the address on its own adapter. Use the broker's reachable IP.

Diagnostic Capture with Wireshark

When STATUS stays 16#0000 and the broker never sees a connection, attach Wireshark to both the PLCSIM Virtual Ethernet Adapter and the host's primary NIC:

# capture filter - only the broker port
tshark -i "Siemens PLCSIM Virtual Ethernet Adapter" -Y "tcp.port==1883" -k
tshark -i "Ethernet0"                -Y "tcp.port==1883" -k

Expected healthy sequence: SYN → SYN,ACK → ACK → MQTT CONNECT (0x10) → CONNACK (0x20) → data. If the SYN leaves the PLCSIM adapter but the host's primary NIC never sees it, the issue is the internal bridge; if the SYN reaches the broker IP on the primary NIC but no SYN-ACK returns, the issue is the firewall or the broker binding.

Verification Checklist

Check Pass Criterion Command / Location
PLCSIM instance state RUN, RUN LED solid green PLCSIM Advanced UI
Virtual adapter IP Static, on the same subnet as the broker ipconfig /all
PG/PC interface S7ONLINE → PLCSIM adapter TIA Portal → Options
Broker binding 0.0.0.0:1883 netstat -ano | findstr :1883
Firewall rule Allow outbound TCP 1883 for PLCSIM Get-NetFirewallRule -DisplayName "*PLCSIM*"
TCP reachability SYN,ACK returned within 2 s tnc <broker_ip> -Port 1883
MQTT round-trip Publish echoed on mosquitto_sub within 200 ms Host CLI
Block status Connected = TRUE, Error = FALSE Watch table

Frequently Asked Questions

Why does the MQTTClient work on a physical S7-1500 but not on PLCSIM Advanced 3.0 with no error code?

The physical CPU uses the host's primary NIC, while PLCSIM Advanced routes traffic through the Siemens PLCSIM Virtual Ethernet Adapter. If the broker is bound to 127.0.0.1 only, the broker's IP is unreachable from the virtual adapter, and the library returns 16#0000 because the failure happens inside the TCP layer, below the MQTT state machine.

Which MQTTClient library version matches TIA Portal V16?

Use the V16 build published under Siemens Support entry ID 109748955. V17/V18 libraries load but fail to instantiate; do not copy a library from a newer project into a V16 project.

Do I need to open any Windows Firewall ports for the PLCSIM MQTT traffic?

Yes. Add an outbound rule for TCP 1883 (or 8883 for TLS) and tag the Siemens PLCSIM application explicitly: New-NetFirewallRule -DisplayName "PLCSIM MQTT" -Direction Outbound -RemotePort 1883 -Protocol TCP -Action Allow -Program "%ProgramFiles%\Siemens\Automation\PLCSIMADV\bin\PLCSIMAdv.exe".

Can I use localhost as the broker host in the MQTTClient DB?

Not under PLCSIM Advanced 3.0. The simulated CPU resolves localhost to the IP on its own virtual adapter, not the host's loopback. Use the broker's actual IPv4 address (for example, 192.168.1.20), and confirm with tnc <broker_ip> -Port 1883 that the path is reachable.

Does TLS work the same way under PLCSIM Advanced 3.0?

TLS works once the plain TCP path is healthy, but the certificate's CN/SAN must match the hostname (not the IP) used in the connection resource. Import the broker's CA into the TIA certificate manager. Reference: Siemens entry 109769956 — S7-1500 security basics.

Back to blog