Skip to content
ssldays

Guide

Where nginx stores SSL certificates and renewal

Document nginx ssl certificate path conventions—Lets Encrypt live symlinks, ssl_certificate directives, stream blocks, and certbot renew with nginx -t reload order.

Updated May 23, 2026 803 words

nginx ssl certificate path hygiene keeps ssl_certificate and ssl_certificate_key aimed at renewed fullchain and privkey files—live symlinks, consistent hooks, and reload after every ACME success.

Engineers asking about nginx ssl certificate path need a map from certbot or vendor deliverables to the directives nginx actually reads on reload. Unlike Apache’s per-module labels, nginx uses paired ssl_certificate and ssl_certificate_key directives in server and stream contexts.

Default tutorials symlink into /etc/letsencrypt/live/HOST/, but real fleets scatter paths under /etc/ssl/nginx, /opt/certs, and config management templates. Renewal updates the wrong directory when only one environment followed the tutorial.

This guide standardizes path discovery with nginx -T, ACME renewal order, stream versus HTTP separation, and post-renew verification. Start from nginx SSL certificate expired if notAfter already passed on the wire.

What to check

Run nginx -T on the production instance that owns the listening socket, including inside containers where host paths differ from bind-mounted volumes.

For nginx ssl certificate path audits, list every ssl_certificate value, its matching key line, and the server_name or stream upstream context. Wildcard certs referenced from multiple files need each reference confirmed after renew.

Certbot live symlinks: fullchain.pem for ssl_certificate and privkey.pem for ssl_certificate_key is the common pattern. Avoid pointing only at cert.pem unless you serve chain via separate files intentionally.

Kubernetes secrets mounted into pods are paths from nginx’s perspective—renew upstream in cert-manager before blaming nginx conf inside the pod.

Step-by-step

Effective configuration dump

nginx -T 2>/dev/null | awk '/server_name|ssl_certificate/'

Save output to the ticket; redact unrelated internal names if needed.

Certbot inventory

certbot certificates
readlink -f /etc/letsencrypt/live/www.example.com/fullchain.pem

readlink reveals the archive revision certbot currently exposes.

Disk validity

openssl x509 -in /etc/letsencrypt/live/www.example.com/fullchain.pem -noout -dates -serial

Align paths in site config

Edit the site file under sites-enabled or conf.d so ssl_certificate paths reference live fullchain unless policy forbids symlinks—in that case automate copy hooks to your fixed paths and reload.

Dry-run renew and hook test

certbot renew --dry-run

Fix failures via Certbot renew failed troubleshooting.

Production renew and reload

certbot renew
nginx -t && nginx -s reload

Details in reload nginx after SSL renewal.

Serial check

echo | openssl s_client -connect www.example.com:443 -servername www.example.com 2>/dev/null | openssl x509 -noout -serial

How to read the output

nginx -T interleaves server_name with ssl directives inside each server block—order matters when several blocks listen on the same IP with different SNI names.

certbot certificates Certificate Path should resolve to the same inode nginx opens post-reload when symlinks are used.

serial from openssl s_client is the operational acceptance metric after path or renew work.

Common mistakes

Relative ssl_certificate paths resolved from the wrong working directory in include files—prefer absolute paths in production.

Stream block still pointing at /etc/nginx/ssl/old-tcp-fullchain.pem while HTTP vhosts already symlink to live.

Forgot privkey permissions after umask changes—nginx -t may pass but reload logs SSL_CTX_use_PrivateKey_file errors.

Two nginx masters after bad package install; hooks signal the inactive binary.

Staging server configs copied to production with HOST-specific paths still embedded.

Relying on certbot nginx plugin paths on one host while other hosts use webroot certonly without updating matching paths.

GitOps repos sometimes store only nginx.conf references while certificates remain host-local. Path documentation must state which machine owns renew authority and which repos merely reference mount points, or reviewers approve merges without noticing path drift.

Immutable infrastructure images bake certificates into AMI layers against security policy. When policy shifts toward live renew, migrate paths deliberately rather than layering certbot on top of AMIs still pointing ssl_certificate at baked PEM paths.

Partner white-label domains may use identical server block templates with different live directories. Templating engines need per-tenant path variables reviewed when one tenant renews but shares a template revision with neighbors.

Performance testing often disables optional TLS settings that share certificate paths with production. After performance events, confirm nobody left temporary self-signed paths in shared snippets promoted to production includes.

Edge functions in front of nginx cannot fix origin expiry. Path work on origin remains mandatory even when CDN edge certificates are fresh—monitor both hostnames in runbooks where architecture splits responsibilities.

Platform engineering guilds should publish a single internal standard for whether staging mirrors production path layout literally or uses shortened test lineages. Inconsistent standards cause false confidence when staging renew succeeds but production paths diverge.

Certificate transparency logs help confirm which hostname set a public CA issued even when on-disk filenames use internal codenames. Cross-check issuance with CT search when path folders use non-obvious labels.

When swapping cloud load balancers, export the nginx path map from the retiring termination tier before routing changes. New tiers may reuse lineages while old PEM paths remain referenced in forgotten includes.

Quarterly game days should include rotating one non-critical lineage through renew, path verification, reload, and external serial proof without touching production commerce domains—practice reduces nginx ssl certificate path confusion during real incidents.

When to use automation

Configuration drift across regions outpaces manual grep quarterly. Live TLS monitoring catches hosts still serving old serials despite uniform path documentation.

ssldays validates public presentation. Add domains at /register with 30, 14, 7, and 1 day alerts—email everywhere, Slack and Discord webhooks on paid plans. Free 3 daily; Starter 25 hourly; Pro 100 hourly. RDAP supplements nginx ssl certificate path programs when domain validation might fail next cycle.

Frequently asked questions

Include snippets per site?

Recommended—each customer site file lists its live paths so one renew does not require editing a monolithic nginx.conf.

Docker volume layout?

Mount /etc/letsencrypt/live read-only into the container path nginx configs expect; reload the container process after host renew.

Wildcard single path?

One fullchain can serve many server_names if SAN covers them—still reload after renew touches the file inode.

When to duplicate PEMs instead of symlinks?

Regulated environments sometimes ban symlinks—use certbot deploy hooks to copy into fixed paths and document copy locations in CMDB.

Monitor this hostname on a schedule

Live certificate checks and renewal reminders — not guesswork from PEM files.