Resolving LHTTP TLS Error 16#8601 on S7-1500 TIA V16

David Krause15 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

Resolving LHTTP_Post TLS Error 16#8601 on S7-1500 with TIA Portal V16

The LHTTP communication library is the canonical Siemens-supplied way to send HTTP and HTTPS (TLS-secured) requests from an S7-1500 CPU to a remote web service. The library wraps the lower-level TCON, TSEND, TRCV, and TLS_/TLC_ primitives in reusable function blocks such as LHTTP_Post and LHTTP_Put. When a TLS handshake fails inside this stack, the block surfaces a status of 16#8601 at the status output. Because that single code is shared by name resolution errors, TCP connect failures, TLS alert messages, and certificate-validation failures, the practical job of the engineer is to narrow the root cause to the certificate trust chain. This reference walks through the diagnosis and resolution path on a SIMATIC S7-1511-1 PN running TIA Portal V16, where the certificate assignment workflow differs from the V17 "Connection Mechanisms" workflow that most public examples assume.

Affected versions: TIA Portal V16 (all updates) and S7-1500 CPUs with firmware V2.6 or higher. The block library itself is version-agnostic; the differences are in the certificate-binding UI in the hardware configuration, which is the source of the confusion when migrating from a V17 sample project to a V16 production project.

1. Problem Description

A customer-side JSON endpoint is reachable from Postman, curl, and standard browsers on the engineering station. When the same URL and payload are submitted from the S7-1511 using LHTTP_Post (or LHTTP_Put) with the UseTLS input set to TRUE, the request never leaves the PLC. The status output returns 16#8601 and the busy flag drops to FALSE within a few hundred milliseconds — well below the configured request timeout. No bytes are written to responseData and no HTTP response code is reported at httpStatus because the TLS handshake terminated before the HTTP request was dispatched.

The functional block is otherwise correctly wired: URI resolves in DNS from the CPU (verified with ping from the engineering PC and from the PLC web server's diagnostic page), the local CPU time is valid for certificate-notBefore/notAfter checks, and the destination port (typically 443) is reachable across any firewalls in the path. Postman on the same engineering workstation completes the same exchange without warnings, which isolates the failure to the PLC-side TLS stack.

2. Error Code 16#8601 — What It Actually Means

The 16#8601 status is the LHTTP library's generic "connection / TLS failure" envelope. Internally, the block inspects the lower-level connection status of the underlying TCON/TLC instance and propagates the failure. The following table summarises the most common sub-causes and the engineering signal that confirms each one.

Sub-cause Underlying status (DWord) How to confirm
DNS resolution failure 16#8602 variants, WSAHOST_NOT_FOUND Disable TLS — if HTTP works but HTTPS fails, it is not DNS.
TCP connect refused / unreachable WSAECONNREFUSED, WSAETIMEDOUT Run a sustained ping from the CPU and verify the firewall.
TLS alert: unknown CA 16#8601 + 0x0200 alert The server's CA chain is not in Global Omniscient or the Trusted Certificates and Root Certification Authorities store of the CPU.
TLS alert: bad certificate 16#8601 + 0x0100 alert Server cert is expired, not yet valid, or its CN/SAN does not match the host portion of the URL.
TLS alert: protocol version 16#8601 + 0x0700 alert Server requires TLS 1.2+ with a cipher the CPU firmware does not support. Compare FAQ 109763879 firmware matrix.
No certificate bound to the connection 16#8601 immediately on first call No certificate is assigned under Properties > Certificate Manager in the device configuration (V16 path).

In a V16 project, the most frequent cause is the last row of the table: the certificate assignment workflow is fundamentally different from V17, and most published examples assume V17's Connection Mechanisms editor.

3. TIA Portal V16 vs V17 — The Real Difference

Siemens introduced a unified certificate-binding UI in TIA Portal V17 (HSP-enabled firmware ≥ V2.9 on the S7-1500). Under that flow, an S7-1500 device in the project tree exposes a Connection Mechanisms node, and the user can pick a certificate from the certificate manager as part of the connection definition. The LHTTP block then reads that assignment implicitly through the device configuration.

In TIA Portal V16, that Connection Mechanisms node is not present. Certificates must be imported through the device certificate manager and then explicitly referenced at the block instance or in the block's cert / certID input parameter — depending on the version of the LHTTP library used. This is the source of the most common confusion when engineers try to follow the official Telegram-messenger example (which is documented for V17 and newer) in a V16 environment.

Engineering rule: When the working project is on TIA V16 and the example is on V17, do not assume the V17 device-configuration steps exist. Treat the certificate binding as a program-side concern (block input parameter or DB constant) and verify by looking at the compiled block interface, not the hardware configuration.

4. Certificate Chain — Which File Goes Where

Modern public-facing endpoints present a chain of three certificates:

  1. Root CA — self-signed certificate that anchors trust.
  2. Intermediate CA — signed by the root, signs the leaf.
  3. Leaf (server) certificate — bound to the public DNS name of the endpoint.

The S7-1500 CPU only needs the chain up to a certificate it already trusts. If the CPU's Trusted Certificates and Root Certification Authorities store does not already contain the issuing root, the engineer must import the root CA certificate — not the intermediate, and not the leaf. Importing the leaf is a common misstep: the leaf is signed by the intermediate, which is signed by the root, and the CPU has no way to validate the leaf if the root is not trusted.

The official Siemens FAQ demonstrates this with the Telegram API, where the API serves a leaf that is chained to a public root. The FAQ explicitly tells the reader to import the root certificate (Section 2.3.2 of FAQ 109763879). The same logic applies to any custom customer endpoint.

4.1 How to extract the correct certificate

For an HTTPS endpoint visible from a browser, the chain can be exported as follows:

  1. Open the endpoint in a browser and click the padlock icon.
  2. Choose Connection is secure > Certificate is valid > Details.
  3. Switch to the Certification Path tab.
  4. Select the topmost certificate in the path (the root).
  5. Click View Certificate > Details > Copy to File and export as Base-64 encoded X.509 (.CER).

For an endpoint that is not browser-reachable, OpenSSL on the engineering workstation produces the same artefact:

openssl s_client -showcerts -connect api.example.com:443 </dev/null 2>/dev/null \
  | awk '/-----BEGIN CERTIFICATE-----/{i++} i==1' > root_ca.cer

The resulting root_ca.cer is the only file that should be loaded into the CPU. Repeating the same command but for i==2 yields the leaf certificate, which is not what the S7-1500 needs.

5. Prerequisites

Before changing the project, confirm that the following preconditions are met:

  • TIA Portal V16 Update 7 or later installed.
  • S7-1511-1 PN with firmware ≥ V2.6 (V2.9 recommended for the broader TLS 1.2 cipher set).
  • LHTTP library version compatible with V16, imported as a global library (the LHTTP V1.0 documentation is available as the official PDF: 109763879_LHTTP_DOC_V10_en.pdf).
  • Engineering PC with read access to the project file and write access to the connected CPU.
  • The root CA certificate for the customer endpoint available as a Base-64 X.509 file.
  • CPU's date and time synchronised (NTP or set manually) — TLS validation rejects certificates whose notBefore/notAfter window does not include the system clock.

6. Step-by-Step Resolution

The procedure below applies to TIA Portal V16. Where the V17 path differs, the difference is noted in brackets.

6.1 Open the certificate manager

  1. In the project tree, select the S7-1500 CPU device.
  2. Open Properties > Certificate Manager.
  3. Switch to the Trusted Certificates and Root Certification Authorities tab.

6.2 Import the root CA

  1. Click Add and select the exported root_ca.cer.
  2. Confirm the fingerprint shown against the customer's published fingerprint (if any).
  3. Set the usage to TLS.
  4. Compile the project (Hardware and Software).

6.3 Bind the certificate to the LHTTP instance (V16)

In V16 there is no Connection Mechanisms node, so the binding is a program-side action. Two patterns are supported by the library:

  • Pattern A — Global certificate: Import the root, then mark it as Global Omniscient in the certificate manager. The LHTTP block will accept any certificate chain rooted at a global omniscient CA without further configuration.
  • Pattern B — Instance-bound certificate: Wire a SystemCert-type tag to the block input. Create a global DB of type SIEMENS_tls_CertRef (or the equivalent V16 data type) and assign the imported CA's ID to it.

Pattern A is the simpler and is the one demonstrated in the Siemens FAQ.

Why Pattern A works in V16: The CPU only stores the root, not the full chain, in this case. The TLS client validates the leaf against the intermediate and the intermediate against the root that is now in the trust store. The intermediate does not need to be imported explicitly; it is delivered to the PLC by the server during the TLS handshake and validated transitively.

6.4 Verify the block call

  1. Confirm the block instance's UseTLS input is TRUE.
  2. Confirm URI uses the fully qualified domain name that matches the leaf certificate's CN or SAN — not an IP address, unless the certificate has an IP-address SAN.
  3. Confirm the port matches the TLS port (typically 443).
  4. Trigger a single execution by setting execute for one PLC cycle.

6.5 Download to the CPU and observe

  1. Download the hardware configuration first, then the software.
  2. Open an online watch table on the instance DB.
  3. Trigger a request and watch the status output.

7. LHTTP Block — Inputs and Outputs Reference

The exact interface depends on the LHTTP library version. The V1.0 interface (documented in the PDF referenced above) is reproduced in skeleton form below.

Parameter Direction Type Notes
execute IN BOOL Rising edge starts the request.
URI IN STRING[254] Full URL, must match the certificate SAN.
method IN STRING GET, POST, PUT, DELETE.
UseTLS IN BOOL Set TRUE for HTTPS endpoints.
headers IN Variant / STRING JSON-friendly header lines.
requestData IN Variant / STRING Body, e.g. the JSON payload.
timeout IN TIME Default 30 s; raise to 60 s for slow endpoints.
busy OUT BOOL High while the block is processing.
status OUT DWORD 16#0000 on success. 16#8601 means TLS/connection failure.
httpStatus OUT DWORD HTTP status (200, 201, 4xx, 5xx) — only valid on TLS success.
responseData OUT Variant / STRING Body of the server response.
diagnostics OUT STRING Human-readable detail, useful in the watch table.

8. Status Code Mapping for TLS Failures

When status is in the 16#86xx range, decode the lower 16 bits to localise the failure. The following mapping is from the LHTTP V1.0 documentation:

Status Meaning Recommended action
16#0000 OK No action.
16#8601 General TLS / connection failure Inspect diagnostics; the most common cause is an untrusted root CA.
16#8602 DNS resolution failed Verify the CPU's DNS server configuration.
16#8603 TCP connect timeout Check firewall, route, and server availability.
16#8604 Send/receive timeout Raise timeout input.
16#8605 TLS handshake alert received Inspect alert level/description in diagnostics and map to the table in section 2.
16#8606 Certificate validation failed Re-import the root CA; verify clock and certificate validity window.

9. Verification

After the certificate is imported and the project is reloaded, run the verification sequence below before declaring the issue closed.

  1. Trigger one LHTTP_Post call from the watch table.
  2. Confirm status transitions to 16#0000 and busy returns to FALSE.
  3. Confirm httpStatus matches the expected HTTP code from the server (e.g. 200 for a successful POST).
  4. Inspect responseData for the expected payload echo or acknowledgement.
  5. Repeat the call several times under load to rule out intermittent failures.
  6. If a server-side log is available, confirm the PLC's source IP and the User-Agent string sent by LHTTP appear in the access log.

On the server side, capture the TLS handshake parameters with a tool such as openssl s_client from the engineering workstation. Compare the negotiated cipher and TLS version against the S7-1500 firmware's capabilities. Firmware V2.6 supports TLS 1.2 with a limited cipher set; firmware V2.9 expands the supported ciphers and is required for some modern endpoints.

10. Common Pitfalls and Field Notes

10.1 Importing the leaf instead of the root

This is the single most common mistake. The leaf cannot validate itself; it must be validated through its chain. Import the root and mark it as a global omniscient CA (or instance-bound, depending on the pattern chosen).

10.2 Using an IP address in the URI

Most public CAs do not issue certificates with IP-address SANs. If the URI is https://192.168.1.50/endpoint and the certificate has a DNS SAN of api.example.com, the TLS handshake fails the SAN check and surfaces as 16#8601. Use the fully qualified domain name that matches the certificate.

10.3 Clock drift

CPU clocks that are off by more than a few minutes will reject valid certificates. Configure NTP in the device properties or synchronise manually before the first request.

10.4 Mixing V16 and V17 documentation

The Telegram example, and most modern Siemens examples, are written for V17. The visual "box" for connection mechanisms does not exist in V16, and chasing that UI in V16 wastes time. The V16 path is the certificate manager plus the program-side binding.

10.5 Proxy and certificate-pinning servers

If the engineering workstation uses a corporate proxy with a man-in-the-middle certificate, the Postman success does not prove the PLC will succeed. The PLC has its own trust store, and corporate proxy CAs are not in it by default. Either bypass the proxy on the PLC path or import the proxy's CA into the CPU.

10.6 Windows-side TLS regressions

Engineering workstations running Windows can lose compatibility with certain TLS versions after security updates. The behaviour of the engineering software (TIA Portal, TIA Administrator) is not the same as the PLC firmware, but a check of the engineering PC's TLS stack can save time if the same code runs on Postman on a different machine. Microsoft's KB 931125 troubleshooting article documents one such regression path; the resolution is not directly applicable to the PLC but is useful as a reference for what can go wrong on the workstation side.

11. Diagnostic Flowchart

The following inline SVG captures the decision tree that an engineer should walk through when status = 16#8601.

Status = 16#8601 Disable UseTLS; retry. Does HTTP succeed? No DNS / firewall issue Yes Re-enable UseTLS. Is the root CA imported? No Import root CA, mark Global Omniscient, recompile and re-download. URI host matches cert SAN? CPU clock within validity window? Open diagnostics string; map to section 8 status table.

12. Extended Diagnostics — When 16#8601 Persists

If the procedure above returns 16#8601 repeatedly, descend to the following deeper checks before assuming a hardware or firmware issue.

12.1 Inspect the diagnostics string

The LHTTP block exposes a diagnostics output that contains the lower-level TLS alert level and description in plain text. Read it in the watch table. Alerts fatal(2) with description unknown_ca(48) confirm an untrusted root; bad_certificate(42) confirms an expired or mismatched certificate; protocol_version(70) confirms a TLS-version mismatch.

12.2 Verify the certificate fingerprint server-side

Capture the certificate the server actually presents with:

openssl s_client -connect api.example.com:443 -servername api.example.com </dev/null 2>/dev/null \
  | openssl x509 -fingerprint -sha256 -noout

Compare the SHA-256 fingerprint against the customer's published fingerprint and against the certificate that was loaded into the CPU (the certificate manager's detail view shows the same fingerprint). A mismatch indicates the wrong certificate was imported.

12.3 Test with a public test endpoint

Point the LHTTP block at a known-good endpoint such as https://api.telegram.org (which is the example target in FAQ 109763879). If that succeeds, the PLC's TLS path is healthy and the issue is specific to the customer's chain. If it also fails, the problem is on the PLC side — usually an incomplete project download (the hardware configuration containing the new certificate did not reach the CPU) or a memory-reset that wiped the imported CA.

12.4 Check the certificate store size limit

The S7-1500 has a finite certificate-store capacity (firmware-dependent; typically 16 KB for the runtime certificate store and 32 KB for the trust store). If the project accumulates many certificates from past projects, the new root may not fit. Clear unused certificates in the certificate manager and re-compile.

13. Pre-Production Checklist

Use this checklist before commissioning a TLS-enabled LHTTP deployment:

  • Root CA of the target endpoint imported and marked Global Omniscient in the device certificate manager.
  • URI uses the FQDN that matches the certificate SAN; no IP addresses.
  • CPU clock synchronised (NTP recommended).
  • Firmware ≥ V2.9 on the S7-1511 for the broadest TLS 1.2 cipher compatibility.
  • LHTTP library version matches the TIA Portal version (V16-compatible LHTTP for V16 projects).
  • Firewall rules permit outbound 443 from the CPU's IP.
  • Engineering workstation can reach the endpoint with Postman or curl as a baseline.
  • Watch table verified: status = 16#0000, httpStatus = 200, expected payload in responseData.

14. References to Official Documentation

The following Siemens resources are the authoritative source for the LHTTP library, certificate handling in TIA Portal, and the V16/V17 differences:

FAQ

What does status 16#8601 mean in LHTTP_Post?

It is the generic TLS / connection failure code returned when the TCP connect, TLS handshake, or certificate validation step fails. The diagnostics output string contains the lower-level TLS alert (for example unknown_ca(48) or bad_certificate(42)) that pinpoints the actual sub-cause.

Which certificate do I import — root, intermediate, or leaf?

Import the root CA certificate as a trusted root, and mark it as Global Omniscient in the device certificate manager. The intermediate and leaf certificates are presented by the server during the handshake and validated transitively against the trusted root.

Why does the V17 Telegram example not work in my TIA V16 project?

TIA Portal V17 introduces a Connection Mechanisms editor in the device configuration that lets the user pick a certificate visually. That node does not exist in V16, where the certificate binding is done through the program-side input parameters or by marking the imported root as globally trusted.

Postman works from the engineering PC but the PLC fails — why?

The PLC has its own TLS trust store, independent of the engineering workstation. Corporate proxy CAs, custom intermediate CAs, and self-signed roots must be imported into the S7-1500's certificate manager. Postman's success is a necessary but not sufficient condition for PLC success.

How do I read the TLS alert that caused 16#8601?

Add the LHTTP instance DB to a watch table, force a request, and read the diagnostics string output. It contains the TLS alert level and description. Compare those against the IANA TLS alert registry to localise the failure (for example alert 48 maps to unknown_ca).

Back to blog