BadCertificateChainIncomplete
BadIssuer chain
BadCertificateChainIncomplete means the validator could not build a path from the peer certificate up to a trust anchor because an intermediate CA certificate is missing. Put the missing intermediates in the issuer store, or configure the peer to send its full chain in OpenSecureChannel.
What you actually see
A CA-issued certificate fails validation even though the root CA is trusted, and the error mentions an incomplete or unbuildable chain rather than a trust problem.
Why it happens
- The server sends only its leaf certificateOpenSecureChannel carries the sender certificate, and a compliant server may send the whole chain. Many send only the leaf. If the leaf was issued by a sub-CA that the client does not hold, chain building in validation step 4 has nothing to link to the trusted root.
- Intermediates are missing from the issuer storeThe issuer store is exactly for this: CA certificates needed to complete a chain, without conferring trust. If your PKI has a root plus one or two sub-CAs and you only distributed the root, every leaf issued by a sub-CA fails here.
- The intermediate is in trusted but the root is not present anywhereTrusting an intermediate directly can work, but only if the validator accepts it as an anchor. Some stacks still walk to the root and require it. Deploying root to trusted and intermediates to issuer is the layout that behaves consistently across stacks.
- Certificates are in the wrong file format or the store index is staleStores expect DER or PEM files in the certs subdirectory; a PKCS#7 or PFX bundle dropped in is ignored. Some stacks build an index at startup, so a file added while the process is running is not seen until reload.
- The chain is broken by a re-issued CAWhen a sub-CA is renewed with a new key, leaves signed by the old key need the old sub-CA certificate to remain in the issuer store. Removing it during a CA rollover breaks every certificate issued before the rollover.
How to fix it
In diagnostic order: work down, do not skip ahead.
- Identify the issuer of the failing certificateExport the peer certificate from the rejected store and run openssl x509 -in peer.der -inform der -noout -issuer -subject. The issuer DN names the CA certificate you are missing. Compare against what is in your issuer and trusted stores.
- Collect the full chain from your PKIGet the root CA and every intermediate as separate DER or PEM files. If you only have a bundle, split it: openssl crl2pkcs7 -nocrl -certfile chain.pem | openssl pkcs7 -print_certs -out split.pem, then separate the blocks.
- Place the root in trusted and the intermediates in issuerCopy the root CA certificate into trusted/certs and each intermediate into issuer/certs under the PKI root the application actually uses. Do this on both peers - the server needs the chain for your client certificate just as much as the client needs it for the server's.
- Add the matching CRLsOnce the chain is complete the validator moves on to revocation checking and you will get BadCertificateIssuerRevocationUnknown if each CA in the chain has no CRL. Drop the CRLs into the crl subfolder of the same store now and avoid a second round trip.
- Reload and retryRestart the application or trigger a trust-list reload, then reconnect. If the error persists with the chain in place, check the CA keyUsage bits, because a CA lacking keyCertSign fails chain building too and can surface as a chain or issuer-use error.
Where it shows up, by tool and stack
| Tool / stack | What to do there |
|---|---|
| UaExpert | Manage Certificates has an Issuers tab distinct from Trusted. Intermediates belong in Issuers. UaExpert treats this error as suppressible so you can connect once for diagnosis, which is a useful way to confirm the chain is the only remaining problem. |
| UA-.NETStandard (C#) | The SecurityConfiguration section has separate TrustedIssuerCertificates and TrustedPeerCertificates store paths, which map to issuer and trusted. Putting intermediates in TrustedIssuerCertificates is the intended layout; the error is suppressible through the CertificateValidation event. |
| asyncua (Python) | Load intermediates explicitly into the certificate validator or add them to the trust store directory you configured. asyncua does not fetch intermediates from the network, so anything not local is simply absent. |
| node-opcua | The certificate manager's issuers/certs folder is where intermediates go; trusted/certs is for anchors. After adding files, call the manager's initialize or restart the process so the internal chain cache is rebuilt. |
| open62541 (C) | UA_ClientConfig_setDefaultEncryption takes trustList and issuerList as separate arrays. Intermediates go in issuerList. Because the lists are compiled in or loaded at startup, chain changes mean a reload on embedded targets. |
| Ignition | The gateway keeps OPC UA client and server certificate stores separately in its configuration UI, each with a quarantine area for rejected certificates and a place for issuer certificates. Adding an intermediate to the wrong one of the two stores is a common cause of this staying unfixed. |
What it looks like in the log
Certificate validation failed. Error: BadCertificateChainIncomplete. Issuer certificate not found for CN=Plant Sub CA 1
Chain build failed: unable to get local issuer certificate for subject CN=plc-01.plant.local
Confirm the fix
Reconnect and confirm the session activates, then check the rejected store gains no new file. Confirm the chain independently with openssl verify -CAfile root.pem -untrusted intermediates.pem peer.pem.
Stop it happening again
Ship the whole chain as one deployment artefact - root into trusted, intermediates into issuer, CRLs into crl - and keep retired CA certificates in the issuer store until every certificate they signed has expired.
Stuck on more than one of these? The troubleshooting clinic works through broken configurations end to end, on camera.
Troubleshooting clinic →Last verified 7 September 2026 against OPC UA 1.05.07. OPC UA Connect is an educational resource and is not affiliated with the OPC Foundation.