Servers and proxies
Nginx SSL_CTX_use_PrivateKey failed: fix the private key
nginx: [emerg] SSL_CTX_use_PrivateKey("/etc/nginx/ssl/example.com.key") failedNginx prints this, or the related cannot load certificate key "...": PEM_read_bio_PrivateKey() failed, when it cannot use the private key in ssl_certificate_key. The text in parentheses after failed is the real reason: a mismatched key, a file that is not a PEM key, an encrypted key, or a file Nginx cannot read.
Quick fix
The reason in parentheses decides the fix.
Validate the key and the certificate pair outside Nginx:
sudo openssl pkey -in /etc/nginx/ssl/example.com.key -noout && echo "key parses"
sudo openssl x509 -in /etc/nginx/ssl/example.com.crt -noout -pubkey | openssl sha256
sudo openssl pkey -in /etc/nginx/ssl/example.com.key -pubout | openssl sha256
Then match the reason Nginx printed:
| Reason in the log | Meaning | Go to |
|---|---|---|
key values mismatch |
key belongs to another certificate | key values mismatch |
no start line, DECODER routines::unsupported |
not a PEM private key | Cause 2 |
bad decrypt, bad password read, passphrase prompt |
encrypted key | Cause 3 |
Permission denied, No such file or directory |
file access | Cause 4 |
Fix, then run sudo nginx -t && sudo systemctl reload nginx.
Causes
1. The key does not match the certificate
A key that does not match the certificate is the most frequent reason behind SSL_CTX_use_PrivateKey ... failed; see key values mismatch.
- Confirm: the two hashes above differ.
- Fix: see Nginx key values mismatch.
2. The file is not a PEM private key
Nginx expects a PEM block such as -----BEGIN PRIVATE KEY-----, BEGIN RSA PRIVATE KEY or BEGIN EC PRIVATE KEY. DER files, PKCS#12 (.pfx/.p12) bundles, a certificate given as the key, or an empty file produce decoder errors such as no start line (OpenSSL 1.1.1) or DECODER routines::unsupported (OpenSSL 3).
- Confirm:
head -1 example.com.keydoes not show aBEGIN ... PRIVATE KEYline, orfile example.com.keyreports binary data. - Fix: convert:
# DER to PEM
openssl pkey -inform DER -in example.com.der -out example.com.key
# PKCS#12 to PEM key
openssl pkcs12 -in site.pfx -nocerts -nodes -out example.com.key
Also check for a UTF-8 byte-order mark or Windows line endings added by an editor (dos2unix removes them).
3. The key is encrypted
Keys created with a passphrase start with BEGIN ENCRYPTED PRIVATE KEY (or contain Proc-Type: 4,ENCRYPTED). Nginx then prompts for the passphrase on the console, and service managers fail with bad decrypt or bad password read.
- Fix: add the passphrase to a root-only file and reference it:
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_password_file /etc/nginx/ssl/example.com.pass;
or decrypt once with openssl pkey -in enc.key -out example.com.key and protect the result with chmod 600.
4. File permissions, paths or SELinux
- Confirm: the message contains
BIO_new_file() failedwithPermission deniedorNo such file or directory. On RHEL-family systems,ls -Zshows a label such asuser_home_tfor files moved from a home directory. - Fix: correct the path, set
chown root:rootandchmod 600, and on SELinux systems restore labels withsudo restorecon -Rv /etc/nginx/ssl.
5. Unsupported key type for the OpenSSL build
Old OpenSSL builds cannot load newer key types, and some FIPS-mode builds reject small or non-approved keys.
- Fix: use an RSA 2048+ or ECDSA P-256/P-384 key, which every current build supports.
Fixes by environment
On every system, Nginx needs a PEM key that matches the certificate, that it can decrypt, and that the master process can read.
Debian / Ubuntu: keys usually live under /etc/ssl/private/ (mode 710, group ssl-cert); keep Nginx's key there or under /etc/nginx/ssl/.
RHEL / Rocky / AlmaLinux: put keys under /etc/pki/tls/private/ or /etc/nginx/ssl/ and run restorecon after copying.
Docker: mount keys read-only and check the user the container starts as; official Nginx images start the master as root, but rootless variants may need the key readable by their user.
Let's Encrypt: reference /etc/letsencrypt/live/<name>/privkey.pem; Certbot writes unencrypted PEM keys with restrictive permissions.
Don't do this
chmod 644or777on the key to "fix permissions". Any local user or compromised web application could then copy the key.- Put the passphrase in the Nginx config or a world-readable file. Use
ssl_password_filewith root-only permissions. - Store keys inside the web root. A misconfigured location block can serve them to anyone.
FAQ
Nginx asks "Enter PEM pass phrase" on every restart. How do I stop it?
The key is encrypted. Either list the passphrase in a file referenced by ssl_password_file (readable only by root), or write a decrypted copy with openssl pkey -in enc.key -out example.com.key and protect it with chmod 600. Automated restarts cannot type a passphrase.
I have a .pfx file from Windows. Which part goes into ssl_certificate_key?
Extract the key with openssl pkcs12 -in site.pfx -nocerts -nodes -out example.com.key and the certificate chain with -nokeys. The SSL converter explains each format.
Does Nginx need the key to be readable by the www-data or nginx user?
No. The master process runs as root and reads certificates and keys at start-up. Keep keys owned by root with mode 600; worker processes do not need access.