Certificate revocation sounds simple on paper. A certificate should stop being trusted before its expiration date, so the issuer marks it as revoked and clients reject it. In practice, it is messier than most administrators expect.
I ran into this the first time I had to replace a certificate after a private key leak. My assumption was straightforward: revoke the old certificate, deploy the new one, and move on. What I noticed instead was that revocation is only as useful as the client checking it, the CA publishing it, the network allowing it, and the browser deciding not to soft-fail. That is a long chain of “ifs.”
If you manage web servers, APIs, mail servers, load balancers, or internal PKI, you should understand what revocation is supposed to do and where it breaks down. This is the version I wish someone had explained to me earlier.
Why certificate revocation exists
A certificate normally stays valid until its Not After date. That can be 90 days for Let’s Encrypt, longer for many enterprise and private PKI deployments, or very short in tightly controlled environments. Revocation exists for the cases where waiting for natural expiry is not acceptable.
The usual reasons are familiar:
- the private key was exposed
- the certificate was issued to the wrong party
- a hostname should no longer be covered
- the organization changed ownership or legal status
- the CA made an issuance error
- malware or a compromised device enrolled a certificate it should never have had
In other words, revocation is the emergency brake.
The important practical lesson is this: revocation is not a replacement for short certificate lifetimes. I prefer short lifetimes because they reduce how long a bad certificate can remain useful even when revocation checks fail. Revocation is still necessary, but it is not strong enough to be your only safety mechanism.
For related background, see how TLS handshakes actually work and how certificate chains are built and validated.
Where revocation information lives in a certificate
A certificate can point clients to revocation data through X.509 extensions. The two that matter most are:
- CRL Distribution Points (CDP): URLs where the client can download a Certificate Revocation List
- Authority Information Access (AIA): often includes the OCSP responder URL
You can inspect both with OpenSSL:
openssl x509 -in server.crt -noout -text
Look for sections like these:
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.exampleca.com/exampleca.crl
Authority Information Access:
OCSP - URI:http://ocsp.exampleca.com
If those extensions are absent, revocation checking becomes limited or impossible unless the client uses other mechanisms.
A quick way to inspect a live site is:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -text
That is one of the commands I use when I want to see what the server is actually presenting rather than what someone thinks it is presenting. It also helps confirm that a replacement certificate really made it to the edge node or load balancer.
CRL: the original revocation mechanism
A Certificate Revocation List is exactly what the name suggests: a CA publishes a signed list of certificate serial numbers that should no longer be trusted.
The basic CRL flow looks like this:
- A CA revokes a certificate.
- The CA adds its serial number to the CRL.
- The CA publishes the updated CRL at the CDP URL.
- A client downloads the CRL and checks whether the serial number appears.
That model is simple and still widely supported. It is also the part that becomes painful at scale.
What CRLs do well
CRLs have a few practical strengths:
- easy to understand
- easy to mirror and cache
- work in offline-ish environments if pre-fetched
- signed by the CA, so tampering is detectable
- useful in internal PKI where you control clients and update schedules
In private PKI, I still see CRLs used successfully, especially for VPN, smart card, and client certificate environments where endpoints are domain-managed and predictable.
The CRL size problem
The weakness is that a CRL is a list, and lists grow.
A busy public CA can revoke a large number of certificates. That means the CRL file can become large enough to hurt connection setup or cause stale-cache behavior. I have seen environments where revocation checks were theoretically enabled but practically useless because endpoints were using outdated CRLs or timing out while trying to fetch them.
With CRLs, the client downloads the whole list even though it only needs to know the status of one certificate. That design was acceptable in older, more centralized environments. On the public internet, it is inefficient.
You can inspect a CRL file locally like this:
openssl crl -in exampleca.crl -inform DER -noout -text
Or for PEM:
openssl crl -in exampleca.crl -inform PEM -noout -text
When troubleshooting, I usually check three things first:
Last UpdateNext Update- whether the target serial number is present
Common CRL mistakes
These are the mistakes I see most often:
- publishing the CRL URL internally where external clients cannot reach it
- letting the CRL expire without regeneration
- rotating CA infrastructure but forgetting old CDP URLs still appear in issued certificates
- serving the CRL over a flaky endpoint with poor caching behavior
Validation is easy:
curl -I http://crl.exampleca.com/exampleca.crl
curl -O http://crl.exampleca.com/exampleca.crl
openssl crl -in exampleca.crl -inform DER -noout -text
If the URL is dead or the Next Update time has passed, you already have a revocation reliability problem.
OCSP: asking about one certificate at a time
Online Certificate Status Protocol was introduced to solve the “download the entire list” problem.
Instead of fetching a big CRL, the client sends a status request for one certificate to the CA’s OCSP responder. The response typically says one of three things:
goodrevokedunknown
This is far more efficient than CRLs for public web traffic. It also introduces a new issue: now the CA can learn which sites clients are connecting to.
Non-stapled OCSP
In the older, direct model:
- the browser receives the server certificate
- it reads the OCSP responder URL from AIA
- it contacts the responder itself
- it asks for the status of that certificate
That works, but it adds latency and leaks metadata. The CA, or whoever operates the responder, can observe a stream of certificate status lookups that correlates with browsing behavior.
This is one reason privacy-minded operators have never loved classic OCSP.
OCSP stapling
OCSP stapling improves that design.
The server periodically fetches a signed OCSP response from the CA and “staples” it to the TLS handshake. The browser can then validate revocation status without making its own direct request to the CA.
Benefits:
- lower client latency
- reduced load on the CA responder
- better privacy than direct OCSP lookups
- fewer outbound client dependencies
If I have a public HTTPS site under my control, I prefer stapling whenever the CA supports it.
There is a more detailed configuration article here: OCSP stapling in Nginx.
How OCSP stapling looks in Nginx
A typical Nginx configuration includes:
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/ca-chain.pem;
resolver 1.1.1.1 1.0.0.1 valid=300s ipv6=off;
resolver_timeout 5s;
A few practical notes from experience:
ssl_trusted_certificateshould include the issuer chain used to verify the OCSP response.- If DNS resolution on the server is broken, stapling breaks quietly or half-works.
- After enabling stapling, always reload and test from outside the box.
Reload Nginx safely:
sudo nginx -t && sudo systemctl reload nginx
Check whether a stapled response is being served:
echo | openssl s_client -connect example.com:443 -servername example.com -status
Look for output similar to:
OCSP response:
======================================
OCSP Response Status: successful
Cert Status: good
If you see no response sent, the configuration or upstream CA support needs work.
Apache OCSP stapling basics
Apache configuration is different but the goal is the same:
SSLUseStapling On
SSLStaplingCache shmcb:/var/run/ocsp(128000)
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors Off
Then validate and reload:
sudo apachectl configtest
sudo systemctl reload apache2
Or on RHEL-like systems:
sudo httpd -t
sudo systemctl reload httpd
I have seen Apache stapling fail because the cache path did not exist, SELinux blocked access, or the issuer chain was incomplete. Those are still worth checking before you blame the CA.
OCSP Must-Staple: useful, but not magic
Some certificates include the TLS Feature extension commonly called OCSP Must-Staple. The intent is clear: a compliant client should require a stapled OCSP response and treat the connection as invalid if the staple is missing.
That sounds attractive, especially if you dislike browser soft-fail behavior. But it raises the operational stakes. If your server stops stapling due to DNS problems, CA responder outages, broken chain files, or misconfiguration, clients that honor Must-Staple can fail hard.
You can inspect the extension with:
openssl x509 -in server.crt -noout -text | grep -A3 "TLS Feature"
I only recommend Must-Staple when you understand your deployment pipeline well enough to test stapling continuously. Otherwise you risk self-inflicted outages.
Browser behavior when OCSP is unreachable: the soft-fail problem
This is the part many people find frustrating.
If a browser cannot reach the OCSP responder, or the response is missing, or the network blocks the check, many browsers soft-fail. That means they continue the connection instead of rejecting the certificate.
Why? Because hard-failing on every revocation lookup problem would make the web fragile. CA outages, captive portals, enterprise filtering, and broken middleboxes would cause a lot of legitimate sites to fail.
From an operator’s perspective, soft-fail weakens revocation. A revoked certificate may not be rejected immediately by every client in every condition.
That is why I treat revocation as one control among several:
- short lifetimes
- prompt certificate replacement
- CT log monitoring
- key protection
- stapling where possible
If you are not already watching CT logs, this pairs well with certificate transparency logs and why they matter.
Chrome CRLSet and similar browser-side mechanisms
Chrome historically used CRLSet, a compact browser-maintained blocklist for a subset of revoked certificates. The key phrase is “subset.” CRLSet was never a complete replacement for the web PKI revocation system.
It was mostly aimed at high-impact revocations such as major CA incidents and high-profile misissuance. That means:
- it can protect users from some dangerous revoked certs
- it does not contain every revoked certificate
- you should not assume your routine revocation will be enforced by CRLSet
Browsers have evolved their own approaches over time, but the big practical point remains: browser-side revocation assistance is selective and not comprehensive.
What happens when a certificate is revoked in practice
When a certificate is revoked, several things are supposed to happen:
- the CA records the revocation reason and timestamp
- the certificate serial appears in the CRL and/or yields
revokedvia OCSP - clients that perform and honor revocation checks reject the certificate
- administrators deploy a replacement certificate
In real operations, the effects depend on client type.
Browsers
Browsers may reject immediately if they have a strong revocation signal, especially with a stapled revoked response or major browser-managed blocklist coverage. They may also continue under soft-fail conditions if the revocation path is unavailable.
API clients and command-line tools
Some tools do very little revocation checking by default. Others can be configured to do more. I have seen teams assume that “TLS validation” automatically included reliable revocation checking in every client library. It often does not.
Enterprise endpoints
Managed desktops, VPN clients, and middleware can enforce CRL or OCSP much more strictly than consumer browsers. In those environments, revocation may be more meaningful because you control both ends of the policy.
How to check revocation status with OpenSSL
The quickest place to start is the live TLS connection.
Check for OCSP stapling:
echo | openssl s_client -connect example.com:443 -servername example.com -status
To extract the certificate and inspect issuer details:
echo | openssl s_client -connect example.com:443 -servername example.com -showcerts 2>/dev/null
If you already have the leaf and issuer certificates, you can query an OCSP responder directly:
openssl ocsp \
-issuer issuer.pem \
-cert server.pem \
-url http://ocsp.exampleca.com \
-resp_text \
-noverify
A direct response may show:
server.pem: good
This Update: Jul 22 11:00:00 2026 GMT
Next Update: Jul 29 11:00:00 2026 GMT
Or, for a revoked certificate:
server.pem: revoked
Revocation Time: Jul 20 08:14:37 2026 GMT
For CRL-based checks, download the CRL and inspect it:
curl -O http://crl.exampleca.com/exampleca.crl
openssl crl -in exampleca.crl -inform DER -noout -text
Then compare the serial number from the certificate:
openssl x509 -in server.pem -noout -serial
Troubleshooting revocation problems
When revocation status is not behaving the way you expect, I work through a short list.
1. Confirm the certificate actually changed
I have seen “revocation problems” that were really deployment problems. The edge node was still presenting the old certificate.
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -serial -issuer -dates
2. Check AIA and CDP URLs
Make sure the certificate points to reachable endpoints.
openssl x509 -in server.pem -noout -text | grep -A5 "Authority Information Access"
openssl x509 -in server.pem -noout -text | grep -A5 "CRL Distribution Points"
3. Validate the responder or CRL endpoint from the server and from outside
curl -I http://ocsp.exampleca.com
curl -I http://crl.exampleca.com/exampleca.crl
Outbound filtering on the server is a common reason stapling fails.
4. Test stapling specifically
echo | openssl s_client -connect example.com:443 -servername example.com -status
If the response is absent, check resolver configuration, issuer chain files, and server logs.
5. Distinguish revoked from unreachable
A responder timeout is not the same as a revoked answer. Logically obvious, but easy to blur during incident response.
Security considerations and current best practice
A few practical conclusions have held up well for me:
Short-lived certificates help more than people expect
Ninety-day certificates are not a nuisance in a well-automated environment. They are risk reduction. If a key compromise occurs and revocation checking is inconsistent, a short lifetime limits the blast radius.
Stapling is worth enabling
For public web servers, stapling improves privacy and efficiency. It is not complicated once you understand the trust chain and DNS dependencies.
Do not rely on revocation as your only defense
Revocation is necessary, but it has known limits:
- soft-fail client behavior
- client inconsistency
- privacy trade-offs in direct OCSP
- stale CRLs
- server misconfiguration breaking stapling
Monitor what the public internet sees
After certificate replacement or revocation, validate externally. Do not stop at local file inspection. Tools like openssl s_client tell you what the service is really presenting. I use them constantly, and in complex cases I also compare with OpenSSL chain verification techniques and an s_client-focused debugging workflow.
Deprecated ideas and current reality
A few assumptions are outdated and worth saying plainly.
Deprecated assumption: revocation always protects users quickly
Not reliably. It can, but not universally.
Deprecated practice: treating CRLs alone as enough for public web PKI
For internet-facing services, CRLs alone are usually too blunt and too heavy. OCSP and stapling are more practical, though still imperfect.
Current reality: layered controls matter more
What works today is a combination of:
- short certificate validity
- automation for renewals and replacement
- revocation support through OCSP and stapling
- CT monitoring
- disciplined key handling
Conclusion
Certificate revocation exists because certificates sometimes become unsafe before they expire. CRLs were the original answer, and they still make sense in controlled environments. OCSP improved efficiency, but introduced privacy and reliability trade-offs. Stapling made OCSP better for web servers, yet browser soft-fail behavior still limits how forcefully revocation is enforced on the public internet.
That is the real-world takeaway I use: enable revocation mechanisms, especially OCSP stapling, but do not overestimate them. Keep certificate lifetimes short, protect private keys, monitor issuance, and always verify from the outside after an incident. Revocation matters. It just does not work like a perfect kill switch.