0X80090325

SEC_E_UNTRUSTED_ROOT (0x80090325) — fix when TLS cert chain breaks

Cybersecurity & Malware Intermediate 👁 29 views 📅 May 27, 2026

Happens when Windows can't trust a server's root CA cert. Common after proxy inspection, broken PKI, or expired intermediates. Here's the real fix.

When does this error actually show up?

You're running a PowerShell script that makes an HTTPS call, or maybe a .NET app trying to talk to an API. The connection drops immediately with SEC_E_UNTRUSTED_ROOT (0x80090325). I've seen this most often on Windows 10 22H2 and Server 2022 boxes behind corporate proxies that do SSL inspection. The proxy replaces the server's certificate with its own, but the proxy's root CA isn't in the machine's Trusted Root store. Another common trigger: you manually added a self-signed root CA but missed an intermediate in the chain, or the root expired and Windows no longer trusts it.

What's actually happening here

TLS handshake fails at the point where Windows checks the root certificate against the Trusted Root Certification Authorities store. Schannel (the Windows TLS stack) walks the certificate chain from leaf up. If any CA in that chain — root or intermediate — isn't trusted, or if its validity period is in the past, you get this exact error. The text "issued by an authority that is not trusted" is literal: Windows doesn't have that root in its store, or the root is present but marked as untrusted (yes, you can mark a root as untrusted).

The trick is that this error can also fire if an intermediate CA certificate is missing from the machine, even if the root is trusted. The chain validation fails because it can't build a path from leaf to root.

Fix it — step by step

  1. Find out which root CA is causing the problem.
    Open Event Viewer → Windows Logs → System. Filter by source Schannel. Look for event ID 36888 or 36887 with status code 0x80090325. The log entry usually includes the server's hostname and the hash of the offending root. Write that hash down.
  2. Check the certificate chain manually.
    Use certutil to dump the chain for the failing URL. Run this in an elevated command prompt:
    certutil -urlcache * delete
    certutil -verify -urlfetch https://your-failing-server.com
    If the command throws an error about the root not being trusted, certutil will tell you exactly which certificate hash is untrusted. Compare it with the hash from the event log.
  3. Inspect the current root store.
    Open certlm.msc (Local Machine certificate store) as Administrator. Expand Trusted Root Certification AuthoritiesCertificates. Look for the root CA from step 2. If it's missing, you need to add it. If it's present but has a red X or says "Not trusted for this purpose", right-click → Properties → check the Trusted Purposes list.
  4. Add the missing root CA.
    Get the root CA certificate file (.cer or .crt) from your IT team or export it from the server that hosts it. Import it with:
    certutil -addstore -f Root path\to\root-ca.cer
    Or via the GUI: right-click Trusted Root Certification Authorities → All Tasks → Import. Do NOT import into Intermediate Certification Authorities by accident — that's a different store and won't fix this error.
  5. If the root is already trusted but the error persists, check intermediates.
    Look in the Intermediate Certification Authorities store for the intermediate CA that issued your server's leaf cert. If it's missing, Windows can't build the chain. Import the intermediate .cer file using:
    certutil -addstore -f CA path\to\intermediate.cer
    The store name CA is the magic one for intermediates. Don't use Root here.
  6. Clear the certificate cache and retry.
    After adding certificates, flush the cache:
    certutil -urlcache * delete
    certutil -setreg chain\ChainCacheResyncTime @60000
    Then restart your app or browser. The second command forces a cache resync within 60 seconds. Remove that registry value later if you want (it's a debug switch).
  7. Reboot if you're on a domain-joined machine.
    Group Policy sometimes pushes certificate trust lists that override local changes. A reboot ensures the updated store is picked up by all services.

What to check if it still fails

If the error persists, don't start randomly importing certs. Check these three things first:

  • Is the server's certificate itself expired? Run openssl s_client -connect your-server.com:443 (or use certutil). If the leaf cert is expired, no amount of root trust will fix it.
  • Is the root CA marked as untrusted by Group Policy? Run gpresult /h gp.html and look for certificate trust policies. Domain admins can push an untrusted list that blocks specific roots. You can't override that locally — you'd need a policy exception.
  • Are you behind a broken SSL inspection proxy? Some proxies strip the intermediate CA from the chain sent to the client. The server sends its leaf cert, the proxy sends its own leaf, but omits the intermediate. In that case, manually importing the missing intermediate into the machine store (step 5) is the only fix. If the proxy uses a self-signed root that changes daily, you're hosed until IT fixes the proxy config.

One more thing: if this is in a development context and you're dealing with a self-signed certificate from localhost, you can temporarily trust it by adding it to Trusted Root Certification Authorities, but know that's a security risk for production workloads. In staging, at least use a proper internal CA.

Was this solution helpful?