Resolving OPC UA BadCertificateHostnameInvalid on the Siemens SIMATIC IOT2040 with Node-RED
The SIMATIC IOT2040 (Siemens article number 6ES7647-0AA00-1YA2) and the newer IOT2050 (6ES7647-0AA00-1YA2 / 6ES7647-0AA00-2YA2) ship with Node-RED preinstalled on the Example Image SD card. When a flow uses the node-red-contrib-iiot-opcua package and exposes data through the OPC UA IIoT Flex Server node, the embedded node-opcua library creates a self-signed X.509v3 certificate the first time the node is deployed. That certificate is auto-generated with placeholder values for the ApplicationUri and a generic Subject Alternative Name (SAN) of DNS:iot2000 or DNS:iot2040. Any client that reaches the server by IP address (for example opc.tcp://192.168.200.1:48020) instead of the original hostname triggers a hostname check that the certificate cannot satisfy, and the OPC UA stack returns a status code that prevents the session from being created.
This reference explains how the OPC UA security model interacts with the Flex Server, how to diagnose the specific status codes that appear, and how to generate and install a replacement certificate that satisfies UaExpert, custom .NET / Python clients, and the Siemens TIA Portal HMI runtime.
1. Symptoms and Status Codes
The certificate problem surfaces differently depending on the client used. The three observations below all share the same root cause: a mismatch between the values inside the X.509 SAN extension of the server certificate and the endpoint URL the client resolves at runtime.
| Client | Observed Symptom | OPC UA Status Code |
|---|---|---|
| Unified Automation UaExpert | Pop-up "Replaced Hostname": "The hostname of the discovery URL used to call GetEndpoints (iot2000) was replaced by the hostname used to call FindServers (192.168.200.1). Do you also want to replace the hostnames of the EndpointURLs with this hostname?" | StatusCode.Good (warning only) |
| UaExpert (after accepting warning) | Session activation fails with certificate error; UAExpert retries and may still connect after several seconds, but the HMI does not. | Bad_CertificateHostNameInvalid = 0x80160000 |
| Siemens TIA Portal HMI runtime (WinCC Unified / Comfort / KTP) | Connection error in HMI diagnostics; TIA configuration permits tag browsing, runtime shows "Connection interrupted". |
Bad_CertificateHostNameInvalid = 0x80160000 or Bad_CertificateUntrusted = 0x801A0000
|
| node-opcua client (Node-RED OPC UA Client / Flex Client) | Log line "OPC UA connection error: The connection has been rejected by server, Please check that client certificate is trusted by server." | Bad_CertificateUntrusted = 0x801A0000 |
| Generic .NET / Python (asyncua, opcua-asyncio) |
BadDecodingError when an incorrectly formatted certificate is dropped into the runtime folder. |
Bad_DecodingError = 0x80070000 |
The OPC UA status codes are defined in OPC UA Part 4 – Services and Part 6 – Mappings and reproduced in the official OPC UA Specification Part 4. Treat each value as authoritative when interpreting client logs.
2. OPC UA Security Model and Certificate Requirements
OPC UA Part 6 defines a certificate-based trust model. Every server and every client must carry an X.509v3 certificate that the counter-party can validate. The following fields are mandatory for a server certificate and must be present in the Subject Alternative Name extension:
| SAN Entry | ASN.1 Tag | Example Value | When Required |
|---|---|---|---|
| uniformResourceIdentifier (URI) | otherName 1.3.6.1.5.5.7.3.1 / id-opcua-application-uri | urn:siemens:iot2040:opcua:server |
Always. Must equal the ApplicationUri advertised in ServerArray. |
| dNSName | dNSName (2) | iot2040.local |
When clients connect by hostname. |
| iPAddress | iPAddress (7) | 192.168.200.1 |
When clients connect by IP address. |
| application URI (otherName) | otherName 1.3.6.1.4.1.311.20.2.3 (Microsoft) or 1.3.6.1.5.5.7.3.1 (PKIX) | As above | Always. Encoded as UTF-8 string in the otherName value. |
When a client opens a session, the OPC UA stack performs two independent checks against the server certificate:
-
Hostname check. The hostname or IP address the client used to open the transport channel must appear in the SAN as either
dNSNameoriPAddress. A mismatch raisesBadCertificateHostNameInvalid. -
ApplicationUri check. The
ApplicationUriin theServerArrayof the server endpoint must match the URI in the SAN. A mismatch raisesBadCertificateUriInvalid.
The auto-generated certificate of the Flex Server uses urn:opcua:server as ApplicationUri and a single dNSName entry of iot2000. As soon as a client contacts the device by IP, the hostname check fails and the session is rejected.
192.168.200.1) is a runtime workaround that suppresses the "Replaced Hostname" warning in UaExpert. It does not remove the SAN check, which is why a real certificate replacement is required for HMI clients.3. Root Cause Analysis
The node-opcua library bundled with node-red-contrib-iiot-opcua uses node-opcua-certificate-manager to produce the auto-generated certificate. The relevant call is createSelfSignedCertificate() with the following defaults:
| Field | Default Value |
|---|---|
| Common Name (CN) | iot2000 |
| Organization (O) |
open62541 / node-opcua
|
| ApplicationUri (SAN URI) | urn:opcua:server |
| dNSName | iot2000 |
| iPAddress | empty |
| Key Algorithm | RSA 2048 |
| Signature | SHA-256 |
| Validity | 1 year |
The generated PEM file is stored in ~/.node-red/node_modules/node-opcua-certificate-manager/certificates/ on the IOT2040. The corresponding private key is stored in the same folder as *_private_key.pem. When the Flex Server starts, it loads the certificate, the key, and the issuer chain. Replacing the auto-generated files with a hand-built certificate that contains the correct SAN entries eliminates the hostname and ApplicationUri errors.
4. Prerequisites
Before generating a replacement certificate, verify the following on the IOT2040:
- Hardware. SIMATIC IOT2040 with the Example Image V2.6.0 or later, or SIMATIC IOT2050 with Example Image V1.0.4 or later. The image is available from Siemens Support entry 109741799 (IOT2040) and 109782388 (IOT2050).
-
Node-RED. Version 1.3.x or later. Verify with
node-red --versionon the device after SSH login. -
node-red-contrib-iiot-opcua package. Version 3.x or 4.x. The Flex Server, Flex Client and OPC UA IIoT nodes must be present. Install with
cd ~/.node-red && npm install node-red-contrib-iiot-opcua. The package is published on the Node-RED Flow Library. - OPC UA clients for verification. Unified Automation UaExpert 1.7 or later, and at least one TIA Portal HMI (WinCC Unified, Comfort Panel, or KTP Mobile Panel with OPC UA licence).
- Certificate generation tool. XCA (Cross Certifying Authority) for graphical use, or OpenSSL 1.1.1 / 3.0.x for command-line use.
-
Network parameters. Final hostname and IP address of the IOT2040, for example
iot2040.localand192.168.200.1. These values will be embedded in the SAN.
5. Generating a Compliant Self-Signed Certificate
Two methods are documented: XCA (graphical) and OpenSSL (command line). The OpenSSL procedure is faster and reproducible from a script.
5.1 OpenSSL Method (recommended for repeatable deployments)
Create a configuration file opcua-cert.cnf on the IOT2040 or on a workstation:
[req]
distinguished_name = req_dn
prompt = no
x509_extensions = v3_ca
[req_dn]
CN = iot2040
O = Siemens
OU = Factory Automation
[v3_ca]
subjectAltName = @alt_names
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth, clientAuth
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid, issuer
[alt_names]
DNS.1 = iot2040
DNS.2 = iot2040.local
IP.1 = 192.168.200.1
URI.1 = urn:siemens:iot2040:opcua:flexserver
Generate the key pair and the certificate (valid for 10 years, RSA 2048):
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout iot2040_opcua_key.pem \
-out iot2040_opcua_cert.pem \
-days 3650 \
-config opcua-cert.cnf \
-sha256
Inspect the SAN to confirm the entries:
openssl x509 -in iot2040_opcua_cert.pem -noout -text | grep -A6 "Subject Alternative Name"
Expected output (abbreviated):
X509v3 Subject Alternative Name:
DNS:iot2040, DNS:iot2040.local, IP Address:192.168.200.1,
URI:urn:siemens:iot2040:opcua:flexserver
5.2 XCA Method (graphical)
- Start XCA and create a new database. Open the Certificates tab and click New Certificate.
- Under Source, choose Generate a new key and select RSA 2048.
- Under Subject, set Common Name to
iot2040, Organization toSiemens, and the Application URI field (inside X509v3 Extensions → subjectAltName → otherName) tourn:siemens:iot2040:opcua:flexserver. - Add the subjectAltName entries:
dNSName=iot2040,dNSName=iot2040.local,iPAddress=192.168.200.1. - Set Key Usage to digitalSignature, keyEncipherment, dataEncipherment and Extended Key Usage to serverAuth, clientAuth.
- Sign and export. Use Export → Certificate → PEM and Export → Private Key → PEM. Keep the two files separate.
Copy the resulting iot2040_opcua_cert.pem and iot2040_opcua_key.pem to the IOT2040 with scp.
6. Configuring the OPC UA IIoT Flex Server
The Flex Server node in the Security configuration tab contains a switch that, when enabled, forces the server to load the certificate and the private key from explicit file paths instead of the auto-generated ones.
- Open the Node-RED flow that contains the OPC UA IIoT Flex Server node.
- Double-click the Flex Server node and switch to the Security tab.
- Enable Use individual public certificate and private key files (this option is present in node-red-contrib-iiot-opcua 3.6.0 and later).
- Set Path to public certificate file to
/home/iot2000/.node-red/certs/iot2040_opcua_cert.pem. - Set Path to private key file to
/home/iot2000/.node-red/certs/iot2040_opcua_key.pem. - Set Default ApplicationUri to the same value that was added to the SAN:
urn:siemens:iot2040:opcua:flexserver. - Disable Allow Anonymous only if you intend to push a ClientCertificate. Otherwise keep None as the lowest security policy until a full HMI connection is established.
- Click Done and deploy the flow.
Fix the file ownership so the Node-RED process (running as user iot2000 by default on the IOT2040 image) can read the files:
sudo chown iot2000:iot2000 /home/iot2000/.node-red/certs/*.pem
sudo chmod 600 /home/iot2000/.node-red/certs/iot2040_opcua_key.pem
sudo chmod 644 /home/iot2000/.node-red/certs/iot2040_opcua_cert.pem
Restart Node-RED and observe the log:
systemctl restart node-red
journalctl -u node-red -f
The relevant log line is certificate_manager: certificate loaded from /home/iot2000/.node-red/certs/iot2040_opcua_cert.pem. If the line reads permission denied, re-run the chown/chmod steps. The node-opcua library also requires read access to the issuer chain folder (issuers/) inside the same certs directory; create it if absent and set the same ownership.
7. TIA Portal HMI Client Integration
Once the Flex Server presents a certificate that matches its IP, the Siemens HMI runtime can be configured as an OPC UA client in TIA Portal V17 / V18 / V19. The procedure assumes a Comfort Panel (TP700 / TP900 / TP1200) or a WinCC Unified Panel (MTP700 / MTP1200) with a valid OPC UA licence.
- In the TIA Portal project tree, open Devices & Networks, select the HMI, and switch to Connections.
- Add an OPC UA connection. Set the endpoint URL to
opc.tcp://192.168.200.1:48020. - Under Security policy, select Basic256Sha256 for production deployments, or None for the first acceptance test.
- Under Authentication, select Certificate-based if the Flex Server has been configured with certificate-based user identity, otherwise Anonymous.
- Transfer the IOT2040 server certificate to the HMI runtime: copy
iot2040_opcua_cert.pemto the TIA Portal project folder Certificate manager → Trusted certificates of the HMI device. TIA Portal converts the PEM to the runtime store automatically during transfer. - Compile and download the HMI configuration.
8. Verification and Acceptance Test
Run the following checks after deploying the new certificate:
-
SAN inspection. From a workstation, run
openssl s_client -connect 192.168.200.1:48020 -showcerts(with the Flex Server temporarily set to None security so the TLS handshake completes) and confirm that the certificate presented by the server contains the expected DNS, IP and URI entries. -
UaExpert round-trip. Start UaExpert, drag Custom Discovery, add
opc.tcp://192.168.200.1:48020, and accept the server certificate. The dialog should not raise the Replaced Hostname warning. Drag a tag and confirm the value updates. -
Security mode escalation. In UaExpert, change the security policy of the connection to Basic256Sha256 — SignAndEncrypt. The handshake must complete without
BadCertificateHostNameInvalid. - HMI acceptance. In the TIA Portal HMI project, open Online → Diagnostics for the OPC UA connection. The status must read Connected. If the runtime still shows Connection interrupted, verify that the TIA Portal compiler included the certificate in the HMI image (check Certificate manager → Used certificates after transfer).
- Node-RED log audit. Tail the Node-RED log for one hour of normal operation. No BadCertificateUntrusted or BadDecodingError entries must appear.
9. Security Hardening and Best Practices
- Validity period. 10 years (3650 days) is acceptable for a self-signed production certificate used inside an isolated OT network. For an internet-facing or multi-tenant deployment, drop validity to 825 days to remain compatible with current browser and major CA policies, or move to a corporate CA.
- Key length. 2048 bits is the minimum for OPC UA applications through 2030. Use 3072 or 4096 bits for new deployments where the client device supports it.
-
Subject Alternative Name coverage. Include every hostname and IP address the server will be reached by. A missing entry raises
BadCertificateHostNameInvalidand is the most common cause of failure after the certificate is replaced. -
ApplicationUri. Use a stable URN that embeds the device serial number, for example
urn:siemens:iot2040:SVP<serial>:opcua. Changing the ApplicationUri forces every client to re-trust the server. -
Trusted client store. For two-way authentication, copy the HMI client certificate into the Flex Server's
issuers/folder and restart Node-RED. - Operating system hardening. Restrict SSH on the IOT2040 to a dedicated maintenance VLAN. Disable Allow Anonymous in the Flex Server once the HMI has been migrated to certificate authentication.
- Firmware updates. Keep the IOT2040 Example Image current. The Siemens IOT2040 support entry lists all released images, including security patches for the underlying Yocto/Debian base.
10. Troubleshooting Matrix
| Observed Status Code | Symptom | Likely Cause | Corrective Action |
|---|---|---|---|
BadCertificateHostNameInvalid (0x80160000) |
Session activation fails; HMI shows "Connection interrupted". | SAN does not include the IP/hostname the client uses. | Re-generate the certificate with the correct iPAddress and dNSName entries. Replace the PEM files in ~/.node-red/certs/. |
BadCertificateUriInvalid (0x80160000 sub) |
Client accepts the host but rejects the server identity. | ApplicationUri in the server configuration does not match the URI in the SAN. | Set Default ApplicationUri in the Flex Server node to the exact URI present in the certificate's otherName SAN entry. |
BadCertificateUntrusted (0x801A0000) |
Node-RED client logs report untrusted server; HMI does not connect. | Server certificate not in the client trust store. | Add the server certificate to the TIA Portal HMI's Certificate Manager under Trusted certificates and root certification authorities. |
BadCertificateTimeInvalid (0x80160000) |
Server certificate not yet valid or expired. | Clock drift between the IOT2040 and the HMI, or expired certificate. | Install chrony on the IOT2040 and point it to a corporate NTP source. Regenerate the certificate with a validity of 825 or 3650 days. |
BadDecodingError (0x80070000) |
Server returns decoding error after manual certificate replacement. | Certificate file contains the key (PEM bundle) or the wrong format. | Split the PEM file: certificate only in *_cert.pem, key only in *_key.pem. Use the Flex Server's Use individual public certificate and private key files option. |
permission denied in Node-RED log |
node-opcua-certificate-manager cannot read the PEM file. | User iot2000 does not own the certificate folder. |
Run sudo chown -R iot2000:iot2000 /home/iot2000/.node-red/certs and chmod 600 the private key file. |
| Replaced Hostname warning in UaExpert | Pop-up appears at first connect. | Flex Server advertises iot2000 in GetEndpoints, client uses 192.168.200.1 for FindServers. |
Set the Flex Server's Alternative Hostname field to the IOT2040 IP. The warning then disappears. |
| UAExpert connects but HMI does not | HMI runtime rejects the connection silently. | HMI does not accept UaExpert's certificate-trust decision; HMI requires explicit trust entry. | Add the IOT2040 certificate to the HMI's runtime certificate store and re-transfer the project. |
11. Frequently Asked Questions
Why does UaExpert connect after a few seconds even when the certificate is wrong?
UaExpert implements the OPC UA Replaced Hostname workaround, where the client asks the user to confirm the replacement of the endpoint hostname. After the user clicks Yes, UaExpert downgrades the hostname check from an error to a warning, retries the session, and succeeds. The TIA Portal HMI runtime does not implement this fallback and treats the same status code as fatal.
What ApplicationUri should I use for a Siemens IOT2040 OPC UA server?
Pick a URN that embeds the device identity, for example urn:siemens:iot2040:<serial>:opcua:flexserver. The same string must be entered in the Default ApplicationUri field of the Flex Server and in the certificate's subjectAltName → otherName (URI) entry. Mismatched values raise BadCertificateUriInvalid.
Can I keep Security Policy set to None?
Yes. Security Policy None is permitted by the OPC UA specification and is appropriate for read-only, isolated networks where the integrity of the data is enforced at the network layer. For any deployment that crosses an IT/OT boundary or transports data outside the IOT2040, set the policy to Basic256Sha256 — SignAndEncrypt and replace the auto-generated certificate with one that contains the correct SAN.
How long should the self-signed certificate be valid?
For a self-signed certificate inside an isolated OT network, 3650 days (10 years) is the default. If the certificate is ever published to clients that enforce modern CA/Browser Forum policies, drop validity to 825 days or less. Re-issue before the notAfter date and re-distribute the new certificate to every HMI runtime before the old one expires.
Does the same procedure apply to the SIMATIC IOT2050?
Yes. The IOT2050 runs the same Node-RED and the same node-red-contrib-iiot-opcua package. Generate the certificate with the IOT2050 IP/hostname, copy the PEM files to /home/iot2050/.node-red/certs/, configure the Flex Server's Use individual public certificate and private key files option, and deploy the flow. The TIA Portal HMI configuration is identical.