Status code · Certificates

BadCertificateUntrusted

BadTrust store

BadCertificateUntrusted means the peer's application instance certificate is not in your trusted store, so validation stopped at the trust check. Fix it by moving that certificate out of the rejected store into trusted - on both client and server, because each side validates the other independently.

Defined behaviour: The certificate is not trusted. (our description of the condition this code reports)

What you actually see

The connection dies during OpenSecureChannel, the client shows a trust dialog or a certificate error, and a copy of the offending certificate turns up in the rejected store.

Why it happens

  • Peer certificate never promoted from rejected to trustedValidation step 3 checks the peer certificate against the trusted store and the application's own certificates. On first contact it is in neither, so the stack files it in rejected and returns this code. The rejected store exists precisely so an administrator can inspect the certificate and promote it.
  • Only one direction was trustedOPC UA secure channels are mutually authenticated. Trusting the server certificate in your client is only half the job; the server also validates the client certificate against its own trusted store. A client-side trust prompt that succeeds and then fails again is usually the server refusing your certificate.
  • The certificate was regenerated, so the thumbprint changedMost stacks create a self-signed application instance certificate on first start if none exists. Reinstalling, wiping the pki folder, or running a container without a persistent volume for pki produces a new key pair and a new thumbprint, and the peer's trust list still holds the old one.
  • The CA was put in issuer instead of trustedThe issuer store only supplies intermediates needed to complete a chain; it confers no trust. A root or sub-CA you actually intend to trust must be in trusted. A chain that builds cleanly but is still untrusted is the signature of this mistake.
  • The application is reading a different PKI root than you editedOn Windows the reference stack keeps its own certificate in the X509Store CurrentUser\UA_MachineDefault while trusted, issuer and rejected live under %CommonApplicationData%\OPC Foundation\pki - normally the hidden C:\ProgramData. Editing a pki folder next to the executable then changes nothing. Check the application configuration for the actual store paths.

How to fix it

In diagnostic order: work down, do not skip ahead.

  1. Work out which side rejectedA client-side error names the server certificate; a server-side rejection usually surfaces to the client as a channel that opens then closes, with the real reason only in the server log. Check the server log and the server's rejected folder before touching the client.
  2. Locate the rejected store and confirm the certificate arrivedLook under the PKI root for rejected/certs. Typical roots are %CommonApplicationData%\OPC Foundation\pki on Windows, ~/.local/share/OPC Foundation/pki or an equivalent LocalApplicationData path on Linux and macOS, and whatever the application configuration file declares. Confirm the file's subject and thumbprint match the peer you are connecting to.
  3. Move the file into the trusted storeCopy the DER or PEM file from rejected/certs into trusted/certs and delete it from rejected. Do this on both machines. In UaExpert use Settings, Manage Certificates, select the server certificate and Trust; the same certificate still has to be trusted on the server side separately.
  4. Reload the trust list or restart the applicationSome stacks watch the trust directory and pick up changes immediately; others cache the trust list at startup. If the connection still fails after the copy, restart the server or client process before assuming the copy did not work.
  5. Retry and confirm the failure has moved onA successful trust promotion often exposes the next validation step - a hostname or ApplicationUri mismatch, or a missing CRL. Those are different codes and different fixes, not a sign the trust change failed.
  6. Make the certificate stableIf the thumbprint changes on every restart, mount the pki directory on persistent storage (this is the classic container failure) or point the application at a fixed key file so trust survives redeployment.

Where it shows up, by tool and stack

Tool / stackWhat to do there
UaExpertOn connect UaExpert offers Trust Server Certificate Temporarily or permanently. Permanent writes to its own PKI under the user profile. Its Settings, Manage Certificates dialog lists Own, Trusted, Issuers and Rejected and lets you copy UaExpert's own client certificate out to hand to the server administrator.
UA-.NETStandard (C#)CertificateValidator raises CertificateValidation for suppressible errors; BadCertificateUntrusted is suppressible, so a handler that sets e.Accept = true will connect. Do not ship that unconditionally. AutoAcceptUntrustedCertificates in the SecurityConfiguration section does the same thing globally and belongs in test rigs only.
asyncua (Python)Client.set_security() needs the server certificate path; the server side needs your client certificate registered with its trust store. For a server, ServerCertificateValidator or the user_manager path controls acceptance. Asyncua will not silently accept an unknown peer.
node-opcuaThe certificate manager keeps rootFolder with own, trusted, issuers and rejected subfolders. Copy the peer's DER file from rejected/certs into trusted/certs. OPCUAClient accepts automaticallyAcceptUnknownCertificate for lab use only.
open62541 (C)UA_ClientConfig_setDefaultEncryption takes explicit trust list and revocation list arrays; there is no folder-watching trust store in the default build unless you supply one. Adding a peer means rebuilding or reloading those arrays, which is why embedded targets need the trust material provisioned at deploy time.
OPC PublisherPublisher writes rejected server certificates under its pki volume. The documentation is explicit that auto-accept mode exposes it to man-in-the-middle attacks and must not be used in production; move the certificate to trusted instead, and keep the pki path on a mounted volume.

What it looks like in the log

Certificate validation failed. Error: BadCertificateUntrusted. Subject: CN=MyClient, Thumbprint: <40 hex chars>
Certificate rejected. Stored in rejected store: pki/rejected/certs/MyClient [<thumbprint>].der

Confirm the fix

Reconnect and confirm the session reaches ActivateSession, then check that the rejected store has no new file with that thumbprint and that the certificate is present in trusted/certs on both ends.

Stop it happening again

Issue application instance certificates from one internal CA and distribute only that CA certificate to every trusted store, so new devices are trusted on first connect instead of needing a manual promotion each time.

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.

Free download
OPC UA Status Code Diagnostic Tree
A 15-page diagnostic reference grouping every normative status code by what actually went wrong: with the first action for each, and the four questions that resolve most faults before you read a single code.
Get the free diagnostic tree →
Free, no course, no login