Resolving S7-1500 MQTT Error 80E4 with AWS IoT Certificates

David Krause13 min read
S7-1200SiemensTroubleshooting
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 Overview

When publishing MQTT data from a SIMATIC S7-1500 CPU to AWS IoT Core using the Siemens LMqtt_Publisher (or LMqttqdn variant) from the open-communication library referenced in Siemens Support entry 109748872 – "MQTT client for S7-1200/S7-1500", the FB returns error 80E4 on the status output even though the same X.509 certificates function correctly in external test clients such as MQTT.fx.

Symptom signature: LMqtt_Publisher.status = 16#80E4 (decimal 32996). No CONNECT packet reaches the AWS IoT endpoint. TCP connect succeeds (port 8883), but TLS handshake fails at the certificate stage. mqtt.fx or aws-iot-device-sdk-v2 with the same *.pem.crt + *-private.pem.key pair works without modification.

The error class 80E_ maps to the TLS/certificate processing layer inside the S7-1500 user-communication firmware. The lower 12 bits identify the specific certificate processing sub-state; 80E4 is the "certificates configured but trust chain / role assignment invalid" branch of the certificate manager.

Root Cause Analysis

Three independent defects combine to produce 80E4 on a fresh deployment:

  1. Format defect: The PLC certificate store accepts only PKCS#12 (.p12) bundles or pre-imported Siemens certificates. AWS IoT issues *.pem.crt + *-private.pem.key in PEM form. They must be packed into a single .p12 container with OpenSSL before they can be associated with the CPU.
  2. Role-mapping defect: TIA Portal's certificate manager distinguishes "Certificate of partner devices" (the broker's chain) and "Device certificates" (the CPU's own identity). Swapping these two roles — or assigning only one of them — is the most common cause of 80E4.
  3. Subject-Alt-Name defect: The validateSubjectAlternateNameOfServer flag in tcpConnParams must reflect the AWS endpoint FQDN (for example xxxxxxxxxxxxxx-ats.iot.eu-central-1.amazonaws.com). If the PLC cannot resolve the SAN, the handshake is aborted even though the chain is valid.

The combination of all three defects produces 80E4. Fixing any single defect still leaves the connection failing with a different TLS sub-error, so all three must be corrected in the order documented below.

Prerequisites

  • SIMATIC S7-1500 CPU with firmware V2.5 or higher (open-communication TLS requires V2.0+; mutual TLS with X.509 chains is stable from V2.5; recommended V2.9.x for current TIA Portal V16/V17 compatibility).
  • TIA Portal V16 or higher (Basic or Professional). V15.1 archives are read-only on V16, which is a frequent stumbling block when reusing example projects.
  • LMqtt_Publisher / LMqttqdn_Publisher FB library (current version 2.0.x; check the version column in the "Instructions" task card and use the latest revision of every TCON, TSEND, TDISCON block used inside the FB).
  • OpenSSL 1.1.1 or 3.x (Windows binaries from Shining Light Productions or built into Git for Windows).
  • AWS IoT Core Thing already created with attached certificate and active policy. Required downloads from the AWS IoT console (Secure → Certificates → your certificate):
  • DNS server reachable from the CPU (use 8.8.8.8 or the plant DNS forwarder; the S7-1500 must resolve the AWS endpoint hostname for SAN matching).

Step 1 — Acquire and Validate AWS IoT Certificates

From the AWS IoT console, navigate to Manage → All devices → Things → <your thing> → Certificates. Download:

  • The device certificate PEM file.
  • The private key PEM file. Never re-download after the initial creation; AWS only stores the private key at creation time. If it was not saved, rotate the certificate.
  • The Amazon Root CA 1 from the official trust repository.

Verify the certificate chain locally before touching the PLC:

openssl x509 -in xxxxxxxxxx-certificate.pem.crt -text -noout
openssl verify -CAfile AmazonRootCA1.pem xxxxxxxxxx-certificate.pem.crt

A successful verify returns xxxxxxxxxx-certificate.pem.crt: OK. If verification fails, the certificate was issued by an older CA chain (Starfield G2, VeriSign G3, etc.) — re-select the correct root CA per the AWS IoT server authentication reference.

Step 2 — Convert PEM to PKCS#12 with OpenSSL

The TIA Portal certificate manager imports a single .p12 file per device identity. Combine the device certificate and its private key into one encrypted container:

openssl pkcs12 -export \
  -in   xxxxxxxxxx-certificate.pem.crt \
  -inkey xxxxxxxxxx-private.pem.key \
  -out  aws-thing.p12 \
  -name aws-thing-cert \
  -CAfile AmazonRootCA1.pem \
  -caname amazon-root-ca-1 \
  -chain

Flags used:

  • -export — emit PKCS#12.
  • -in — device certificate.
  • -inkey — device private key (PEM, RSA 2048-bit typical).
  • -name — friendly name visible in the TIA Portal certificate manager.
  • -CAfile / -caname / -chain — embed the issuing CA inside the bundle so the PLC can present a complete chain when mutual TLS is requested.

OpenSSL will prompt for an export password. The password is required at import time in TIA Portal. Use a strong password (≥ 16 chars) — it is stored in the TIA Portal project, not on the PLC, so complexity matters less than traceability. Do not add -passout pass: in production; the password is echoed to the shell history.

Validate the resulting file:

openssl pkcs12 -in aws-thing.p12 -info -nokeys -nodes | head -40

Confirm that -----BEGIN CERTIFICATE----- appears twice (device + CA) and that -----BEGIN PRIVATE KEY----- or -----BEGIN RSA PRIVATE KEY----- is present.

Step 3 — TIA Portal Certificate Manager Configuration

Open the project, then Project tree → Security → Certificate manager. The Siemens documentation "Using the TIA Portal certificate manager" describes the manager in detail. The configuration below assumes global certificate manager; the project-local manager exposes the same fields but is scoped to the active project only.

  1. Import the Amazon Root CA 1. Right-click Trusted certificates and root certificate authorities → Import → select AmazonRootCA1.pem. Set the usage to "TLS server certificate". The default issuer name is "Amazon / Starfield Services"; leave it untouched.
  2. Import the device certificate (P12). Right-click Device certificates → Import → select aws-thing.p12. Enter the export password from Step 2. TIA Portal will create two entries: the device certificate and the embedded CA chain.
  3. Assign the certificate to the CPU. In the project tree, open Devices & networks → <S7-1500 CPU> → Properties → Security → Certificate manager. Two fields are mandatory:
    • Certificate of partner devices → select the Amazon Root CA 1 entry.
    • Device certificate → select the aws-thing-cert entry (the one bound to the device's own key).
  4. Compile the project and download the hardware configuration. The certificate IDs are now stored in the CPU; record the two numeric IDs — they are required for the data block in Step 4.
Mapping rule: The "partner device" certificate authenticates the server the CPU connects to. The "device certificate" authenticates the CPU itself during mutual TLS. AWS IoT Core enforces mutual TLS on the default 8883 endpoint. Swapping the two assignments is the most common reason for 80E4 because the CPU then presents the server's CA as its own identity, and AWS rejects the handshake.

Step 4 — LMqtt_Publisher Data Block Configuration

Open the instance DB generated by the LMqtt_Publisher FB. The tcpConnParams structure is the only place where the certificate IDs, port, broker, and DNS are wired together. Populate it exactly as follows:

DB element Type Value (example) Notes
connectType BOOL TRUE 1 = new connection, 0 = re-use existing
ipVersion USINT 4 IPv4 (set to 6 only if AWS endpoint is reached via IPv6)
port UINT 8883 AWS IoT TLS listener
broker STRING[255] 'xxxxxxxxxxxxxx-ats.iot.eu-central-1.amazonaws.com' For LMqttqdn variant only; leave empty for LMqtt_Publisher
HW_ID HW_IO 269 Hardware identifier of the PROFINET interface on the CPU
validateSubjectAlternateNameOfServer BOOL TRUE Matches the AWS endpoint FQDN against the server certificate SAN
idTlsServerCertificate UDInt Amazon Root CA 1 ID from Step 3 This is the partner certificate
idTlsOwnCertificate UDInt aws-thing-cert ID from Step 3 This is the device certificate

To read the numeric certificate IDs from the TIA Portal project, open Certificate manager → <certificate> → Properties → "Certificate ID". The same IDs are listed in the CPU's security diagnostics under Online & diagnostics → Security → Certificate manager.

Set the topic, QoS, retain, and payload fields according to the AWS IoT shadow or rules engine subscription. A minimal sanity topic is test/plc/payload with QoS 0 and retain FALSE.

Step 5 — DNS and Network Configuration

For the LMqttqdn variant, the PLC performs a DNS resolution of the broker FQDN itself. Configure the DNS server in CPU Properties → PROFINET interface → Ethernet addresses → DNS server:

Primary DNS:   8.8.8.8
Secondary DNS: 1.1.1.1

Verify connectivity from the engineering station first:

nslookup xxxxxxxxxxxxxx-ats.iot.eu-central-1.amazonaws.com

If the engineering station resolves the name but the PLC does not, the firewall between the PLC and the DNS server is dropping UDP/53. Add the DNS server to the router/firewall rules before continuing.

The CPU must also reach the AWS IoT endpoint on TCP/8883. The Online & diagnostics → Functions → "Connection diagnostics" tool can be used to open a raw TCP test connection:

Target host: xxxxxxxxxxxxxx-ats.iot.eu-central-1.amazonaws.com
Target port: 8883

A successful TCP test is a prerequisite for TLS — if the TCP test fails, certificate work is premature.

Step 6 — Commissioning Sequence

  1. Compile the project (Project → Compile all).
  2. Download the hardware configuration to the CPU. Important: the certificate manager writes its state into protected PLC memory; an interrupted download can leave the certificate table inconsistent. Use Download to target device with the Reset to factory settings option only if the previous certificates are unwanted.
  3. Power-cycle is not required for V2.5+; a STOP → RUN transition is sufficient and recommended over a full download restart.
  4. Reset the rising edge on the enable input of LMqtt_Publisher.
  5. Monitor the status output. Sequence of expected values:
    • 16#0000_0000 — idle
    • 16#8001_0001 — TCP connect in progress
    • 16#8001_0002 — TLS handshake in progress
    • 16#0000_0000 — connected, publishing
  6. On AWS IoT Core, open Test → MQTT test client → Subscribe to topic with test/plc/payload. The first message should appear within 5–10 seconds.
Important: the AWS IoT policy attached to the certificate must include the iot:Connect, iot:Publish, and iot:Receive actions on the resource arn:aws:iot:<region>:<account>:topic/test/plc/* at minimum. A policy that only allows connect-and-receive produces a 401 from AWS after the TLS handshake, which on the PLC side still presents as 80E4 even though the root cause is authorisation. Verify in the AWS IoT logs (CloudWatch → Logs → AWSIoTLogs) by filtering on Reject.

Verification

A complete verification cycle covers three independent layers:

  1. TLS layer — the status output returns 16#0000_0000 within 5 seconds of triggering the publisher, and remains stable across STOP→RUN transitions.
  2. AWS authorisation layer — CloudWatch shows Allow entries for the Connect and Publish actions; no Reject entries within 5 minutes of operation.
  3. Application layer — the payload value in the AWS IoT MQTT test client matches the PLC tag value at the moment of publication. Validate round-trip latency by adding a 32-bit sequence counter to the payload and logging the values in CloudWatch.

Extended Troubleshooting Matrix

Observed status Layer Likely cause Corrective action
16#80E4 TLS / certificates Wrong role mapping, P12 without chain, expired CA Re-do Step 2 and Step 3; confirm OpenSSL -chain was used
16#80E2 TLS / certificates Own certificate missing or not yet downloaded to CPU Re-download hardware configuration; verify certificate manager shows the P12 in green
16#80E1 TLS / certificates CPU firmware older than V2.0 on the affected interface Update CPU firmware; TIA Portal will only allow TLS on CPUs V2.0+
16#80C3 TCP / DNS DNS resolution failure or unreachable broker Use Connection diagnostics for a raw TCP test on port 8883
16#80A7 TCP / port Port 8883 blocked by firewall Allow TCP/8883 to *.iot.<region>.amazonaws.com
16#80A1 TCP / interface Wrong HW_ID Inspect PROFINET interface properties for the hardware identifier
16#0000 but no AWS message AWS / authorisation Policy allows Connect but not Publish Update IAM policy; check CloudWatch AWSIoTLogs
TLS error inside the ServerHello phase S7-1500 firmware Cipher suite mismatch CPU firmware < V2.6 only offers TLS 1.0/1.1; AWS requires TLS 1.2 minimum. Update to V2.9.x

The full set of TLS error codes returned by the SIMATIC open-communication firmware is documented in the Siemens support entry 109751825 – "TLS error codes for SIMATIC S7-1200/S7-1500". The codes 80E0–80EF are reserved for certificate processing; 80F0–80FF for cipher negotiation.

Edge Cases and Field-Proven Caveats

  • CPU firmware pinning. TLS 1.2 with modern cipher suites (ECDHE-RSA-AES256-GCM-SHA384) requires V2.6 or later. AWS IoT Core deprecates TLS 1.0/1.1 on standard endpoints. Confirm the CPU firmware in Online & diagnostics → Diagnostics → CPU before debugging anything else.
  • Multiple certificates in the same project. Each PLC can hold up to 32 device certificates. The numeric IDs are not stable across project renames — record the IDs after every certificate manager edit.
  • OpenSSL 3.x compatibility. The default algorithm in OpenSSL 3.x is SHA-256; AWS IoT uses SHA-256-RSA signatures, so no compatibility flag is required. If a legacy environment is stuck on OpenSSL 1.0.2, add -legacy or upgrade; otherwise the .p12 will be unreadable by TIA Portal V17.
  • Time synchronisation. The PLC certificate is checked against the CPU's local time. A CPU with a wall-clock skew larger than ±5 minutes will produce 80E4 even if the chain is perfect. Use CPU Properties → Time of day → Synchronisation with an NTP source (the same NTP server as the engineering station).
  • V15.1 archive compatibility. TIA Portal V16 cannot open V18 archives, and V16 Basic has restrictions on the open-communication library. V15.1 projects are readable on V16 SP1 or higher; downgrade is not possible.
  • Retain flag. MQTT retain=true is rejected by AWS IoT Core on the default endpoint configuration with the message "Retain flag is not allowed". Set retain := FALSE in the LMqtt_Publisher instance DB to avoid a silent publish-side drop after a successful TLS handshake.
  • Mutual TLS vs. certificate-only authentication. AWS IoT Core uses mutual TLS by default on port 8883. If the AWS endpoint is configured for custom authentication, the PLC must use port 443 with a header-based auth scheme, which LMqtt_Publisher does not support. Verify the endpoint type in the AWS IoT console before assuming mutual TLS.

Frequently Asked Questions

What does S7-1500 error 80E4 mean in MQTT publisher context?

80E4 is a certificate-processing error in the S7-1500 open-communication firmware. The TLS handshake failed at the certificate-validation step. The most common causes on AWS IoT are wrong role assignment of the Amazon Root CA versus the device certificate in the TIA Portal certificate manager, or a .p12 file generated without the issuing CA chain. Recreate the .p12 with openssl pkcs12 ... -chain and remap the two roles exactly as in Steps 2 and 3.

Which Amazon Root CA should I use for AWS IoT in 2024+?

Use Amazon Root CA 1 from https://www.amazontrust.com/repository/AmazonRootCA1.pem for all new AWS IoT endpoints. The legacy Starfield Services Root CA - G2 is still trusted but is scheduled for deprecation per the AWS IoT server authentication documentation. New things created in the AWS console after 2023 default to Amazon Root CA 1.

Can I use TIA Portal V15.1 to import the .p12 generated with OpenSSL 3.x?

No. TIA Portal V15.1 only supports the OpenSSL 1.0.x .p12 format. Use OpenSSL 1.1.1, or upgrade to TIA Portal V16 SP1 minimum. TIA Portal V17+ accepts both 1.1.1 and 3.x generated .p12 containers without conversion. If you must stay on V15.1, generate the .p12 with OpenSSL 1.0.2 and add -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES for legacy compatibility.

Why does MQTT.fx connect with the same certificates but the S7-1500 returns 80E4?

MQTT.fx is a Java application using the Bouncy Castle TLS stack. It does not require a .p12 container, it does not enforce the device-versus-partner role split, and it does not perform SAN validation against the AWS endpoint in the same strict order. The PLC's TLS implementation is stricter; the 80E4 indicates the chain is valid but the role mapping or SAN rule is wrong. Re-do Steps 3 and 4 in the order above; MQTT.fx success is necessary but not sufficient.

Does the PLC need to verify the AWS endpoint subjectAltName?

Yes. Set validateSubjectAlternateNameOfServer := TRUE in the tcpConnParams structure. The PLC matches the AWS endpoint FQDN (e.g. xxxxxxxxxxxxxx-ats.iot.eu-central-1.amazonaws.com) against the SAN of the server certificate. AWS IoT Core presents SAN entries for both the ats and the legacy data endpoints. If the broker string in the DB does not match the FQDN presented by AWS, the TLS handshake terminates with 80E4 even though the chain is valid. The LMqttqdn variant handles this automatically if DNS resolution is configured.

What is the difference between LMqtt_Publisher and LMqttqdn_Publisher?

LMqtt_Publisher takes the broker IP address as a numeric address; LMqttqdn_Publisher takes the broker as a fully-qualified domain name and performs DNS resolution on the CPU. Use the qdn variant for AWS IoT Core because the endpoint IP addresses are subject to change. The qdn variant also requires a configured DNS server in the CPU's Ethernet properties (typically 8.8.8.8). Both variants share the same tcpConnParams structure and the same 80E4 failure mode.

Back to blog