SignTool 0x800B0109: A Certificate Chain Processed, but Terminated in a Root Certificate Which Is Not Trusted
SignTool error 0x800B0109 means the chain Windows evaluated terminated at a root that was not trusted under that verification policy/context. Do not assume that observed chain is the chain you intended, and do not import a root certificate or blindly add /pa first. Identify the artifact, intended policy, observed signer/chain/root, expected chain, and trust context; then fix only the boundary that differs.
/pa versus driver-policy verification./pa, then inspect the chain if trust still fails./kp; for OS-specific driver/catalog validation, Microsoft also recommends specifying the target OS with /o.General Authenticode EXE/MSI:
signtool verify /pa /v "app.exe"Kernel-mode driver policy:
signtool verify /kp /v "driver.sys"30-second decision — which branch should you use?
Start with
signtool verify /pa /v. If 0x800B0109 remains, inspect the chain and trust context below.If kernel-mode policy is what must pass, use
/kp. Do not switch to /pa merely to get a successful result.Skip generic root-store advice and go to the MSIX branch. Microsoft documents Local Computer → Trusted People for this development scenario.
Personal/My = certificates available to that identity; Trusted Root = trust anchors; Intermediate = CA certificates between signer and root; Trusted People = explicitly trusted end certificates used by specific Windows scenarios. These stores are not interchangeable.
Diagnostic flow — artifact → policy → chain → trust context
EXE/MSI, kernel driver/catalog, and MSIX do not share one universal “trust-store fix.”
0x800B0109 identifies an untrusted root in the evaluated path, but that path may not be the issuer/root path you expected. Record signer → intermediates → root before changing trust.
Current User, Local Machine, App Installer, service account, CI runner, or enterprise/GPO-managed root store.
Prefer issuer/organization deployment guidance over ad-hoc manual root imports.
Fix #1 — do not confuse /pa with a universal trust repair
Microsoft documents /pa as the Default Authentication Verification Policy. Without it, SignTool verification can use the Windows Driver Verification Policy. That means adding /pa can be the correct test for a normal Authenticode executable—but it can also hide the fact that you were intentionally testing a driver under a different policy.
/pa. If you must validate kernel-mode signing requirements, keep the appropriate driver policy such as /kp and fix that trust/policy failure instead.Verify: rerun with the intended policy. If 0x800B0109 remains, move to the certificate chain and trust context; do not keep switching flags until one passes.
Fix #2 — inspect the signing certificate and chain before trusting anything
Open the signed file’s Digital Signatures details or use approved certificate tooling to inspect the signer, issuer chain, validity, and root that Windows actually evaluated. Compare that observed chain with the issuer/root path expected from your CA, enterprise PKI or development PKI. If Windows selected or constructed an unexpected path, trusting its terminal root blindly can hide the real chain-distribution/policy problem.
CERT_E_UNTRUSTEDROOT (0x800B0109) means Windows processed a chain to a root that is not trusted. CERT_E_CHAINING (0x800B010A) means a chain to a trusted root could not be built. If your actual code is 0x800B010A, missing intermediate/chain discovery becomes the primary branch; do not treat this 0x800B0109 guide as an exact match.Verify: identify the expected root and intermediate(s), and confirm their fingerprints/issuers through your CA, organization, or development PKI documentation before any store change.
Fix #3 — self-signed/dev certificate: Personal is not Trusted Root
A self-signed certificate can exist in CurrentUser\My or another Personal store and still fail verification. The Personal/My store makes a certificate available to an identity; it does not automatically establish that certificate as a trusted root.
Verify: rerun the intended SignTool policy after the approved development trust is deployed. The chain should terminate at the expected trusted development root—not merely “some certificate that makes verification pass.”
Fix #4 — MSIX/App Installer has its own trust branch
For the Microsoft-documented MSIX development-certificate scenario that produces 0x800B0109, the documented trust step uses Local Computer → Trusted People. Keep this scoped to that development/install model and a certificate whose identity you have validated; enterprise/public production signing should follow its own deployment and trust model.
Verify: after following the applicable Microsoft MSIX development trust procedure for the validated certificate, retry the same package/install path on the same machine context that originally produced 0x800B0109. Do not treat a separate SignTool /pa pass as proof that App Installer's original trust path is fixed.
Fix #5 — Current User vs Local Machine vs service/CI identity
If verification works interactively but fails in a service, installer, build runner, or another account, compare the trust context instead of reissuing the certificate. A service account can have a different user store; an installer can require machine-level trust; enterprise policy can also control which roots are accepted.
whoami
Get-ChildItem Cert:\CurrentUser\Root | Select-Object Subject, Thumbprint
Get-ChildItem Cert:\LocalMachine\Root | Select-Object Subject, ThumbprintVerify: compare only the expected CA/root across the relevant scopes. Do not “synchronize” stores by bulk-importing certificates.
Fix #6 — only branch to intermediates when chain building points there
When the signer should chain to a trusted public or enterprise root but Windows cannot build that expected path, inspect the intermediate CA certificates and chain-discovery path. Intermediate certificates normally belong in the Intermediate Certification Authorities store—not Trusted Root.
Verify: after the approved intermediate is available, rebuild/verify the chain and confirm it reaches the expected trusted root under the intended policy.
Fix #7 — enterprise/GPO case: use CAPI2 before changing managed trust
If a known organizational/public root appears valid but Windows still reports it untrusted—especially on domain-managed machines—inspect the CAPI2 Operational log. Microsoft specifically recommends CAPI2 for diagnosing root-store and chain-policy problems, including Group Policy-managed trust.
Verify: reproduce the failure, correlate the CAPI2 events, and resolve the documented enterprise trust/GPO issue. Do not fight centrally managed trust by manually adding roots to individual machines.
Driver/catalog edge case — verify against the intended Windows version
For driver and system-catalog verification, Microsoft recommends the /o option to specify the operating-system version being targeted. Without it, a catalog that validates for one Windows version can produce an unexpected result when evaluated against another.
Verify: rerun the driver/catalog verification using the intended kernel policy and target OS. Keep 0x800B0109 diagnosis focused on the chain/root Windows evaluates under that real target context.
Final verification — prove the intended policy passes
Repeat verification using the same policy that matters for your artifact. A passing /pa test does not prove kernel-mode policy passes, and a certificate visible in a store does not prove the relevant identity trusts its chain.
signtool verify /pa /v "app.exe"
signtool verify /kp /v "driver.sys"Verify: reproduce the original validation path using the policy/context that actually matters. Confirm the expected signer, observed chain, expected root, timestamp/countersignature where relevant, and verification result rather than treating a different policy or exit code alone as evidence.
What not to do
Still seeing 0x800B0109?
If SignTool cannot find a signing certificate at all, use No Certificates Were Found That Met All the Given Criteria. If signing succeeds but timestamping fails, use Timestamp Server Could Not Be Reached or Returned an Invalid Response.
Official references
Still stuck? Ask the community
Share the artifact type, intended /pa or /kp policy, signer/root identity with sensitive details redacted, trust scope, and the exact 0x800B0109 output.
Loading community discussion…
Comments could not load here. Open ErrorHarbor Discussions on GitHub →