Every time a browser connects to your HTTPS site, it needs to check whether your SSL certificate has been revoked. Traditionally that meant the browser itself contacted the certificate authority’s OCSP (Online Certificate Status Protocol) server directly — which adds latency, leaks a bit of the visitor’s browsing behavior to the CA, and occasionally fails outright if the CA’s responder is slow or down. OCSP stapling flips this: your server checks the revocation status ahead of time and “staples” that signed response onto the TLS handshake, so the browser never has to make a separate call at all.
It’s a small change with a real payoff — faster handshakes, better privacy for visitors, and one less point of failure in your TLS chain. This guide covers what OCSP stapling actually does, how to enable it properly in Nginx, and how to verify it’s really working (a step a lot of guides skip, leaving people with a config that looks right but silently isn’t stapling anything).
How OCSP and OCSP Stapling Work
When a certificate is issued, it includes a URL for an OCSP responder — a service run by the certificate authority that can answer “is this certificate still valid?” Without stapling, here’s what happens on every connection:
- Browser receives your certificate.
- Browser contacts the CA’s OCSP responder directly to check revocation status.
- CA responds “good,” “revoked,” or “unknown.”
- Browser completes the handshake.
That second step is the problem — it’s a synchronous network round trip the visitor’s browser has to make, often to a server they’ve never talked to before, adding real latency and creating a privacy leak (the CA now knows every site that visitor connects to).
With OCSP stapling:
- Your Nginx server periodically fetches the OCSP response from the CA itself (not the visitor — your server does this in the background).
- Nginx caches that signed response.
- When a visitor connects, Nginx “staples” the cached, signed OCSP response directly onto the TLS handshake.
- The browser verifies the stapled response’s signature and trusts it — no separate network call needed.
The response is cryptographically signed by the CA, so the browser can trust it without contacting the CA itself. It’s a genuinely elegant solution to a real performance and privacy problem.
Requirements
- Nginx 1.3.7 or later (basically anything modern) compiled with
--with-http_ssl_module— standard on virtually all distro packages today. - A valid SSL certificate from a CA that supports OCSP (all major CAs — Let’s Encrypt, DigiCert, Sectigo, etc. — do).
- Your certificate chain must include the intermediate certificate, not just your leaf certificate — this is the single most common reason stapling fails.
- Outbound internet access from your server to the CA’s OCSP responder (usually just standard HTTP, port 80 outbound).
- A domain resolving correctly with DNS already set up for your certificate.
Step 1: Confirm Your Certificate Chain Is Complete
OCSP stapling requires Nginx to send the issuer (intermediate) certificate along with your own, because the stapled response needs to be verified against the chain. If you’re using Let’s Encrypt via Certbot, fullchain.pem already includes this — that’s exactly why it’s used instead of cert.pem alone.
Check your chain:
openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -issuer -subject
If you’re managing certificates manually from a commercial CA, make sure you concatenate your certificate with the CA’s intermediate bundle:
cat your_domain.crt intermediate.crt > fullchain.crt
Step 2: Configure Nginx for OCSP Stapling
Edit your server block (or a shared SSL config file included across virtual hosts):
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
# The trusted certificate used to verify the OCSP response signature.
# This should be the CA's chain, NOT including your own leaf cert.
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
# DNS resolver Nginx uses to reach the OCSP responder
resolver 8.8.8.8 1.1.1.1 valid=300s;
resolver_timeout 5s;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
}
Key directives explained:
ssl_stapling on;— enables OCSP stapling itself.ssl_stapling_verify on;— tells Nginx to verify the OCSP response it receives from the CA before stapling it (a good integrity check, catches misconfigured chains early).ssl_trusted_certificate— this is specifically the chain/intermediate certificate, used only for verifying the OCSP response signature. With Let’s Encrypt, this ischain.pem(notfullchain.pem, which includes your leaf cert too — using the wrong file here is a very common mistake).resolver— Nginx needs DNS resolution to reach out to the OCSP responder URL embedded in your certificate. Without a resolver directive, stapling silently fails.
Step 3: Test the Configuration and Reload
sudo nginx -t
sudo systemctl reload nginx
Step 4: Verify Stapling Is Actually Working
This is the step most tutorials skip, and it matters — a broken stapling config doesn’t throw errors, it just silently doesn’t staple anything, and your site keeps working exactly as before (minus the benefit).
Using OpenSSL directly:
echo | openssl s_client -connect example.com:443 -status 2>/dev/null | grep -A 17 "OCSP response"
Look for OCSP Response Status: successful (0x0) and Cert Status: good. If instead you see OCSP response: no response sent, stapling isn’t working.
Using SSL Labs:
Run your domain through SSL Labs’ SSL Server Test — the results page includes an explicit “OCSP Stapling” field that reports Yes/No.
Checking Nginx error logs for stapling issues:
sudo tail -f /var/log/nginx/error.log
If Nginx can’t reach the OCSP responder or the resolver isn’t configured, you’ll see warnings like:
[warn] ssl_stapling ignored, issuer certificate not found
That specific warning almost always means your ssl_trusted_certificate is pointing at the wrong file, or is missing entirely.
Troubleshooting Common Issues
“issuer certificate not found” warning. Your ssl_trusted_certificate isn’t set, or points to a file that doesn’t contain the actual intermediate CA cert. Double-check you’re using the chain file, not the full combined bundle.
OCSP response shows but is stale/old. Nginx caches the OCSP response according to the nextUpdate field the CA provides — this is normal and by design, not a bug. Responses are typically valid for several days.
Stapling works on curl/OpenSSL tests but SSL Labs reports “No.” Check that you’re testing the exact hostname SSL Labs uses, and that any CDN/load balancer in front of your server isn’t terminating TLS itself (in which case stapling needs to be configured there, not on your origin Nginx).
“no route to host” or timeouts in error log. Your resolver can’t reach the internet, or a firewall is blocking outbound port 80/443 to the OCSP responder. Verify with curl -I http://ocsp.your-ca.com from the server itself.
Works after reload but breaks after a while. This can happen if resolver cache validity (valid=300s) is too short combined with a flaky upstream DNS resolver — try a more reliable resolver pair, or extend valid=3600s.
Security Considerations
- OCSP stapling doesn’t replace certificate revocation checking security-wise — it changes who fetches the check and when. It genuinely improves privacy since the CA no longer sees a request for every visitor.
- Use
ssl_stapling_verify on;so Nginx itself validates the OCSP response signature — this catches a misconfigured or compromised chain before it’s served to visitors. - Pair this with strong
ssl_protocolsandssl_cipherssettings — stapling is a nice-to-have layered on top of a properly hardened TLS config, not a substitute for one. - Keep your resolver addresses set to reliable, non-logging DNS providers if privacy is a priority for your deployment (e.g., 1.1.1.1 has a documented privacy policy worth checking against your requirements).
Performance Tips
- Because the OCSP response is fetched once and cached (typically for the
nextUpdatewindow from the CA, often 4-7 days for Let’s Encrypt), the performance cost of stapling on your server is negligible after the first fetch per worker. - If you run multiple Nginx workers, each worker fetches its own OCSP cache independently the first time — this is normal, but on very high-traffic sites with many workers, consider testing under load to confirm no unexpected resolver bottlenecks during a cold start (e.g., right after a reload).
- Combine with HTTP/2 and session resumption (
ssl_session_cache,ssl_session_timeout) for compounding handshake performance gains — stapling handles one part of a slow handshake, session reuse handles another.
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1h;
ssl_session_tickets off;
Real-World Use Cases
- An e-commerce site handling checkout traffic enables stapling to shave measurable milliseconds off every new TLS handshake during high-traffic sales events, when every bit of latency compounds across thousands of concurrent connections.
- A privacy-focused publisher enables OCSP stapling specifically so their CA (and any network observer) can’t build a picture of individual reader visit patterns via OCSP lookups.
- An internal enterprise application behind a reverse proxy enables stapling at the edge Nginx layer to reduce dependency on external OCSP responder uptime, since backend systems shouldn’t be affected by a third-party CA outage.
Best Practices
- Always use the CA’s chain/intermediate file (not the full combined bundle) for
ssl_trusted_certificate. - Set an explicit
resolverwith a reasonablevalidcache time — don’t rely on system defaults. - Verify stapling with an actual test (OpenSSL or SSL Labs) after every certificate renewal, since some ACME clients change file paths or chain formats between versions.
- Monitor Nginx error logs after enabling stapling for at least a few days to catch resolver or chain issues that don’t appear immediately.
- Automate certificate renewal (Certbot with a cron/systemd timer) so the OCSP-relevant chain files stay current without manual intervention.
Wrapping Up
OCSP stapling is one of those TLS hardening steps that costs almost nothing to implement but quietly makes every visitor’s connection to your site a little faster and a little more private. The configuration itself is short — five or six directives — but getting the chain file right and actually verifying it’s working is where most setups go wrong. Take the extra two minutes to check with OpenSSL or SSL Labs after enabling it; a config that “looks correct” but isn’t actually stapling responses is a very easy mistake to ship unnoticed.