How do I install an SSL certificate on Nginx?
To install an Nginx SSL certificate, combine your certificate and the CA’s intermediate certificates into one full-chain file, reference it with ssl_certificate and your private key with ssl_certificate_key in a server block that listens on 443, then run nginx -t and reload. Nginx has no separate chain directive, so the chain must be inside the certificate file.
This guide is the Nginx-specific part of our overview on how to install an SSL certificate. It assumes the certificate is issued and you have the private key created with your CSR (certificate signing request). If you still need a CSR, use our CSR generator or OpenSSL on the server.
| Item | What you need |
|---|---|
| Nginx build | Compiled with SSL support (standard in distribution packages) |
| Files | Server certificate, intermediate (CA bundle), private key |
| Format | PEM (text starting with -----BEGIN CERTIFICATE-----) |
| Access | Root or sudo |
| Port | 443 open in the firewall |
Installed? Check it from the outside
Run your domain through our free SSL checker to confirm Nginx serves the right certificate, a complete chain and the expected expiry date.
Check your Nginx SSL setupNginx SSL certificate setup at a glance
Build the full chain
Concatenate your server certificate and the intermediate certificate(s) into one PEM file, server certificate first.
Protect the key
Store the private key in a directory only root can read.
Edit the server block
Add listen 443 ssl, ssl_certificate and ssl_certificate_key for your server_name.
Test, reload, verify
Run nginx -t, reload gracefully and check the site from outside.
Nginx SSL certificate configuration, step by step
The paths below follow Ubuntu/Debian conventions. On RHEL, AlmaLinux and Rocky Linux, site configs usually go in /etc/nginx/conf.d/ instead of sites-available.
1. Create the full-chain file
Your CA sends the server certificate (for example example_com.crt) and one or more intermediates, often as a .ca-bundle. The server certificate must come before the intermediates; if the order is reversed, Nginx refuses to start with a key mismatch error.
cat example_com.crt example_com.ca-bundle > example_com_fullchain.crt
sudo mkdir -p /etc/ssl/example.com
sudo cp example_com_fullchain.crt /etc/ssl/example.com/
A missing intermediate is the most common reason a site works in one browser and fails in another. Our guide to the certificate chain explains why.
2. Store the private key
sudo cp example_com.key /etc/ssl/private/
sudo chmod 600 /etc/ssl/private/example_com.key
Check that the key matches the certificate before you go further. Both commands must print the same hash:
openssl x509 -noout -pubkey -in example_com.crt | openssl sha256
openssl pkey -pubout -in /etc/ssl/private/example_com.key | openssl sha256
3. Add the certificate to the server block
Edit your site file, for example /etc/nginx/sites-available/example.com:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com www.example.com;
root /var/www/example.com;
ssl_certificate /etc/ssl/example.com/example_com_fullchain.crt;
ssl_certificate_key /etc/ssl/private/example_com.key;
}
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
On Ubuntu/Debian, enable the site with sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/.
4. Test and reload
sudo nginx -t
sudo systemctl reload nginx # or: sudo nginx -s reload
Tip: You never need a full restart to load a new Nginx SSL certificate. A reload starts new worker processes with the new configuration and lets the old workers finish their open connections, so visitors see no downtime.
5. Optional: limit protocol versions
Current Nginx packages already default to modern TLS versions, but many admins set them explicitly so older defaults on legacy systems do not slip through. Add this inside the server block or once in the http block:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
What changes between the two protocol versions is explained in TLS 1.2 vs TLS 1.3. If you install an SSL certificate on Ubuntu with Nginx from the distribution package, the steps above are complete; nothing else needs to be enabled.
Special cases
Self-signed for testing
Fine for a local lab; browsers will warn because no public CA vouches for it.
Kubernetes ingress
The ingress controller reads the certificate from a TLS secret, not from a file path.
Wildcard certificates
Install like any other certificate and reuse the same file pair in each subdomain's server block.
Self-signed certificates and Kubernetes
Nginx does not generate certificates itself. For a test server you can create a self-signed pair with OpenSSL:
openssl req -x509 -newkey rsa:2048 -nodes -days 30 \
-keyout test.key -out test.crt -subj "/CN=localhost"
Browsers do not trust such certificates, so keep them off public sites; the trade-offs are covered in self-signed vs CA-signed SSL. In Kubernetes, ingress-nginx serves a fallback certificate set with the controller argument --default-ssl-certificate=<namespace>/<secret>, where the TLS secret holds the full chain as tls.crt and the key as tls.key. Note that the Kubernetes project retired ingress-nginx: best-effort maintenance ended in March 2026, so plan a move to another controller or the Gateway API.
Where does Nginx store SSL certificate files?
Nginx has no certificate store of its own; it reads the files named in ssl_certificate and ssl_certificate_key. Distributions use these conventional locations:
| System | Certificates | Private keys | Site configs |
|---|---|---|---|
| Ubuntu / Debian | /etc/ssl/certs/ | /etc/ssl/private/ | /etc/nginx/sites-available/ |
| RHEL / AlmaLinux / Rocky | /etc/pki/tls/certs/ | /etc/pki/tls/private/ | /etc/nginx/conf.d/ |
| Official nginx.org packages | any path you choose | any path you choose | /etc/nginx/conf.d/ |
To see which files a running server uses, dump the active config: sudo nginx -T | grep ssl_certificate. For Apache, IIS, Java keystores and desktops, see where certificates are stored on other systems.
How do I host several SSL sites on one Nginx server?
Add one server block per site, each with its own server_name and its own ssl_certificate pair. Nginx uses SNI (Server Name Indication, the hostname the browser sends at the start of the TLS handshake) to choose the right certificate, so all sites can share one IP address.
server {
listen 443 ssl default_server;
server_name shop.example.com;
ssl_certificate /etc/ssl/shop/shop_fullchain.crt;
ssl_certificate_key /etc/ssl/private/shop.key;
}
server {
listen 443 ssl;
server_name blog.example.org;
ssl_certificate /etc/ssl/blog/blog_fullchain.crt;
ssl_certificate_key /etc/ssl/private/blog.key;
}
The block marked default_server (or the first one loaded) answers clients that send no SNI. Run nginx -V and look for “TLS SNI support enabled” if you use a custom build.
Renew or replace the certificate on Nginx
Build a new full-chain file
Combine the renewed or reissued certificate with the current CA bundle; use the new key if you created a new CSR.
Save under a new name
Add a date to the file names so the old pair stays available for a quick rollback.
Update the paths
Point ssl_certificate and ssl_certificate_key at the new files and run nginx -t.
Reload and verify
Reload Nginx and confirm the new expiry date from outside the server.
How do I update the certificate without downtime?
Replace the files, test, reload. If you overwrite the existing files in place, a reload is still required, because Nginx reads certificates only at startup and on reload. As of October 2026, publicly trusted TLS certificates last at most 200 days, falling to 100 days on 15 March 2027 under CA/Browser Forum ballot SC-081, so plan for regular swaps. Timing, reminders and automation to renew an SSL certificate are covered in a separate guide.
Common Nginx SSL errors
| Error or symptom | Likely cause | Fix |
|---|---|---|
SSL_CTX_use_PrivateKey_file ... key values mismatch | Wrong key, or chain before certificate | Put the server certificate first; check the key hash |
cannot load certificate ... No such file | Typo in path or missing file | Fix the path, run nginx -t |
| Fails on Android or in curl, fine on desktop | Intermediate missing | Rebuild the full-chain file |
| Old certificate still served | No reload, or another server block matches | Reload; check nginx -T for duplicate server names |
| Wrong certificate on one site | No matching server_name | Add the hostname, or fix the default_server |
After every change, test the live site with our SSL checker. It shows the certificate Nginx actually serves, the chain and the expiry date.
Verify your Nginx SSL installation
See the served certificate, the complete chain and the expiry date in one check. No login needed.
Run the SSL checker