guidox / Security

Diagnose a Certificate Error with Certutil

TL;DR

Save the server certificate, then run **certutil -verify -urlfetch** on it. The output names the failing chain element, which separates an expired certificate from a missing intermediate.

Before you start

Requirements

  • The host name that fails
  • Admin rights for the machine store
  • 15 minutes
Step by step

Instructions

01

Pull the certificate the server actually sends

The browser hides the chain behind a warning. A direct TLS handshake in PowerShell prints the subject, the issuer and the validity dates without a security prompt.

$h = 'example.com'
$req = [Net.HttpWebRequest]::Create("https://$h")
$req.Timeout = 10000
try { $req.GetResponse() | Out-Null } catch { $_.Exception.Message }
$req.ServicePoint.Certificate | Select-Object Subject,Issuer,GetEffectiveDateString,GetExpirationDateString
02

Check the clock before you check the certificate

A machine that is a day behind fails every freshly issued certificate. **w32tm** shows the offset, and the time zone must match the one the machine is in.

w32tm /query /status
w32tm /stripchart /computer:time.windows.com /samples:3
Get-Date
Get-TimeZone
03

Verify the chain with urlfetch

**certutil -verify** walks the chain and fetches every intermediate from its published URL. A chain that fails only in urlfetch is missing an intermediate on the server.

certutil -urlcache * delete
certutil -verify -urlfetch C:\temp\server.cer
certutil -dump C:\temp\server.cer | Select-String -Pattern 'Subject|Issuer|NotAfter'
04

Look for a proxy or an interception tool

A corporate proxy or a security product replaces the server certificate with its own. That is not a bug, but it fails any client that does not trust the proxy's root.

netsh winhttp show proxy
Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' | Select-Object ProxyEnable,ProxyServer
Get-ChildItem Cert:\LocalMachine\Root | Where-Object Subject -like '*Proxy*'
05

Fix the layer that failed

An expired certificate is a server problem. A missing intermediate is fixed by importing it into **Intermediate Certification Authorities** on the client or on the server.

Import-Certificate -FilePath C:\temp\intermediate.cer -CertStoreLocation Cert:\LocalMachine\CA
Get-ChildItem Cert:\LocalMachine\CA | Select-Object Subject,NotAfter
certutil -verify -urlfetch C:\temp\server.cer
06

Confirm the fix in the application

The chain is cached per process. Restart the browser or the app, then check the connection again with the same PowerShell handshake before declaring it fixed.

Stop-Process -Name chrome -ErrorAction SilentlyContinue
$req = [Net.HttpWebRequest]::Create('https://example.com')
try { $req.GetResponse().StatusCode } catch { $_.Exception.Message }
Get-ChildItem Cert:\CurrentUser\Disallowed | Select-Object Subject
Troubleshooting

Common issues

certutil says the certificate is expired

The server serves an old certificate. Nothing on the client fixes that; check the host from a second network to be sure.

urlfetch fails with a network error

The machine cannot reach the intermediate's URL, often behind a firewall. Import the intermediate by hand or allow the URL.

Only one app fails, the browser works

The app uses its own trust store or an old TLS stack. Update it, or enable TLS 1.2 in the registry for legacy software.

The error appears only on the company network

A proxy is intercepting the connection. Ask for the proxy root certificate and install it in the local machine store.

FAQ

Frequently asked

Is it safe to click through the warning?

Not on a site that handles credentials. A wrong certificate means you cannot tell who is on the other end.

Where do intermediates belong?

In Intermediate Certification Authorities. Root certificates belong in Trusted Root, and a root placed in the wrong store still fails.

Does the browser use the Windows store?

Edge and Chrome do. Firefox keeps its own store by default, which is why one browser can fail while the other works.

How to undo this

Remove any certificate you imported with Remove-Item on the matching Cert: path, then run certutil -urlcache * delete to clear the cached chain.

Changelog · 1 entry
  1. 2026-11-01
    First version
Interactive version: checklist, feedback, related guides →

Free · no account needed · tracks your progress