Expired CRL: an emergency runbook for Microsoft PKI

When a CA's certificate revocation list (CRL) expires, clients can no longer check whether certificates from that CA have been revoked – so they reject them. Wi-Fi with 802.1X, VPN, smart card logon, LDAPS and internal websites go down in one go. The offline root is the classic trap: its CRL is often valid for six months or longer, and nobody remembers the date.

Typical symptoms

  • Error 0x80092013 (“The revocation function was unable to check revocation because the revocation server was offline”)
  • Smart card or Windows Hello logon says the revocation status of the domain controller certificate could not be determined
  • NPS rejects Wi-Fi and VPN logons, with references to the revocation check in the event log

1. Find out which CRL has expired

Export an affected certificate (e.g. a server certificate) as .cer and let Windows fetch the entire chain including CRLs:

certutil -verify -urlfetch C:\temp\server.cer

The output lists the CRL URLs fetched for every CA in the chain and whether they're valid. To check a single CRL file directly, look at the NextUpdate line – that's the expiry date:

Invoke-WebRequest http://pki.contoso.com/CertEnroll/CONTOSO-ROOT-CA.crl -OutFile $env:TEMP\root.crl
certutil $env:TEMP\root.crl

2. Issuing CA (online): publish again

On the issuing CA, as administrator:

certutil -crl

This creates new base and delta CRLs and writes them to every configured location (AD, C:\Windows\System32\CertSrv\CertEnroll, and the web server's file share if configured). If it fails, the “Active Directory Certificate Services” service usually isn't running, or the CA can't write to the web server share (the CA's computer account needs Modify rights). You'll find the publishing locations in certsrv.msc → CA properties → Extensions.

3. Offline root: sign and distribute a new CRL

  1. Start the root CA and check the clock – a wrong system time produces a CRL with the wrong validity period.
  2. Create a new CRL: certutil -crl
  3. Copy the file from C:\Windows\System32\CertSrv\CertEnroll\ via USB stick to the issuing CA or an admin workstation.
  4. Publish it to AD – the last parameter is the root CA's computer name (its container under CDP in AD):
    certutil -dspublish -f "C:\temp\CONTOSO-ROOT-CA.crl" ROOTCA01
  5. Copy it to the web server that clients download it from over HTTP (the URL is listed in the CA certificates under “CRL Distribution Points”).
  6. Shut the root CA down again.

4. Get clients to notice sooner

Clients cache CRLs. They re-download an expired one on their own, but on important servers you can give them a nudge:

certutil -urlcache crl delete
certutil -setreg chain\ChainCacheResyncFiletime @now

# NPS servers (Wi-Fi/VPN): restart the service
Restart-Service IAS

5. Prevent the next outage

  • Give the root CRL a generous validity period with an overlap, e.g. one year with four weeks of overlap. On the root CA:
    certutil -setreg CA\CRLPeriodUnits 1
    certutil -setreg CA\CRLPeriod "Years"
    certutil -setreg CA\CRLOverlapUnits 4
    certutil -setreg CA\CRLOverlapPeriod "Weeks"
    Restart-Service certsvc
    certutil -crl
  • Put it in the calendar: the root CRL's NextUpdate minus a few weeks, with a link to this runbook.
  • Check every publishing location: CRLs often live in two places (AD and HTTP) – and, after migrations, as stale copies in places nobody remembers.

That's exactly what the free ADCS Health Check checks: expiry and freshness of every CRL in AD and over HTTP, stale copies, missing objects and the offline root CRL – with a traffic light and concrete commands in the report.

More guides