Security connection problems
Modbus/TCP Security fails at one of three stages; the start of the message tells you which.
| Stage | Message shape | When |
|---|---|---|
| Reading certificate files | Config(...), Crypto(...), Io(...) |
In connect, before TLS starts |
| TLS handshake | Security("Handshake(...)") |
During connect |
| After connecting | Io(Other, "...SSL alert ..."), exception 01 |
On the first request or at the authorization check |
PDComm never falls back to plain TCP or authentication-only mode when a secure connection fails, and certificate validation can’t be turned off.
Certificate files
Section titled “Certificate files”| Message | Cause and fix |
|---|---|
Config("Chain must include its root CA") |
The chain file doesn’t end with the root CA. Concatenate your certificate, the intermediate CAs and the root CA, in that order. |
Config("Device certificate must be X509v3") |
The device certificate is X.509 v1. Issue a v3 certificate; OpenSSL 3’s x509 -req creates v3 by default. |
Config("Empty certificate chain") |
The chain file contains no certificate. |
Config("Revocation checking requires CRLs") |
require_revocation is true but crls is empty. |
Config("Cannot load CRL") |
A CRL file can’t be read or has the wrong format. |
Crypto(ErrorStack([... "calling fopen(<path>, r)" ...])) |
The private_key or trust file doesn’t exist. Check the path in the message. |
Crypto(ErrorStack([... reason: "key values mismatch" ...])) |
private_key doesn’t belong to the first certificate in chain. |
Io(Os { code: 2, kind: NotFound, message: "No such file or directory" }) |
The chain file doesn’t exist. |
Invalid Security configuration |
chain, private_key or trust is empty, or mode is wrong. security in a serial configuration gives this too. |
TLS handshake
Section titled “TLS handshake”| Message | Cause and fix |
|---|---|
Security("Handshake(\"error:0A000086:SSL routines:tls_post_process_server_certificate:certificate verify failed:...\")") |
The client couldn’t validate the server certificate; see the next table. |
Security("Handshake(\"...ssl/tls alert handshake failure...SSL alert number 40\")") |
The two sides use different mode values or share no cipher. Use the same mode on both; authentication_only needs RSA certificates. |
Security("Handshake(\"unexpected EOF\")") |
The peer doesn’t speak TLS: a secure client connected to a plain Modbus TCP server. |
Io(ConnectionRefused, ...) |
No server listens on that port. Check the secure server’s port, such as 1802 or 802. |
Common causes of certificate verify failed:
| Cause | Check |
|---|---|
| Host name mismatch | The client’s hostname (default localhost) must be in the server certificate’s SAN. When you connect by IP, put that IP into hostname, and the SAN needs a matching IP: entry. |
| Untrusted CA | The client’s trust must be the CA that issued the server certificate. |
| Expired or not yet valid certificate | Check the validity period with openssl x509 -in server.pem -noout -dates, and the computer’s clock. |
| Not v3, or a malformed role extension | Device certificates must be X.509v3, and a role extension must be a single UTF8String. |
When the server rejects the client certificate, TLS 1.3 lets the client’s connect succeed first; the failure shows up on the first request (next section).
Failures after connecting
Section titled “Failures after connecting”| Message | Cause and fix |
|---|---|
Io(Other, "error:0A000414:SSL routines:ssl3_read_bytes:ssl/tls alert certificate revoked:...SSL alert number 44") |
The server found the client certificate revoked in its CRL. Get a new certificate. |
Io(Other, "error:0A000418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:...SSL alert number 48") |
The server doesn’t trust the CA that issued the client certificate. Check that the server’s trust is that CA. |
Io(ConnectionReset, "Connection reset by peer (os error 54)") |
A plain client connected to a secure server. Add security to the client. |
A response with exception 01 (such as [134,1]) |
TLS works, but the server’s role policy doesn’t allow the function. Check the server’s roles and null_role and the role in the client certificate. |
After these failures, state reports connected as false. Fix the cause, then connect again.
Check the role
Section titled “Check the role”Show a client certificate’s role:
openssl x509 -in reader.pem -noout -text | grep -A1 '50316' 1.3.6.1.4.1.50316.802.1: ..reader- Without the extension, the server applies
null_role. - Role names are case-sensitive, and the whole value is one name:
reader,operatoris a single role calledreader,operator, not two roles.
To start over from creating certificates, follow the Modbus/TCP Security tutorial. When you contact support, never send private keys; send certificate fingerprints, validity periods and error messages only.