What Gixy reports
[ssl_stapling_without_resolver] ssl_stapling is enabled but no resolver is configured
Severity: MEDIUM
Reason: ssl_stapling is enabled for this SSL server, but no `resolver`
directive is reachable in its scope - OCSP stapling will
silently fail.
Why a resolver is required
OCSP stapling means nginx fetches the certificate's revocation status from the issuing CA itself, caches it, and attaches it to the TLS handshake. The client gets a signed freshness proof without contacting the CA, which is both faster and better for privacy.
To do that, nginx has to make an outbound HTTP request to the OCSP responder URL embedded in
your certificate -- a hostname. nginx does not use the system resolver for runtime lookups;
it has its own, and it only exists if you configure it. With no resolver in
scope the hostname cannot be resolved, the fetch never happens, and stapling is skipped.
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/example.com.pem;
ssl_certificate_key /etc/ssl/example.com.key;
ssl_stapling on;
ssl_stapling_verify on;
# no resolver anywhere in scope
}
nginx -t passes
The syntax is valid, so the config test succeeds and the server starts. At most you get a warning in the error log at the first handshake. Everything looks configured, and clients are quietly doing their own OCSP lookups -- exactly what you enabled stapling to avoid.
The fix
Add a resolver in the server or http block:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/example.com.pem;
ssl_certificate_key /etc/ssl/example.com.key;
ssl_stapling on;
ssl_stapling_verify on;
resolver 127.0.0.1 valid=300s ipv6=off;
resolver_timeout 5s;
}
127.0.0.1 assumes a
local caching resolver such as unbound or systemd-resolved; your
cloud provider's internal DNS works equally well. Pointing this at
8.8.8.8 or 1.1.1.1 sends every internal lookup off your network in
cleartext and is itself a HIGH finding --
resolver_external.
ssl_stapling_verify on; makes nginx validate the OCSP response signature before
stapling it. It needs the issuer chain available, which is normally satisfied by a full-chain
ssl_certificate file. resolver_timeout 5s; keeps a slow DNS server
from stalling handshakes.
Verify the fix
gixy /etc/nginx/nginx.conf
nginx -t && nginx -s reload
# Ask for a stapled response:
echo | openssl s_client -connect example.com:443 \
-servername example.com -status 2>/dev/null \
| grep -A 17 'OCSP response'
Working stapling prints OCSP Response Status: successful followed by the
validity window. Broken stapling prints OCSP response: no response sent.
Give it a moment. nginx fetches the OCSP response lazily -- the very first handshake after a reload usually goes out unstapled while the fetch happens in the background. Run the command twice.
When this is a false positive
Let's Encrypt certificates. Let's Encrypt
stopped serving
OCSP on 2025-08-06. If your certificate comes from them, stapling has nothing to fetch
and the right change is to remove ssl_stapling rather than to add a resolver.
Gixy has a separate check for precisely this --
ssl_stapling_letsencrypt
-- so if you see both findings on the same server, act on that one.
Otherwise this finding is reliable. A resolver is either reachable in scope or
it is not, and Gixy resolves inheritance from http down to server
the same way nginx does.
Reference
- ssl_stapling_without_resolver in the Gixy documentation — what the check inspects and its options
- All Gixy checks — the full list by severity
- Plugin source — the exact detection logic