The error you're encountering is quite specific:
nginx: [emerg] SSL_CTX_use_certificate_chain_file("/path/to/cert.pem") failed (SSL: error:02001002:system library:fopen:No such file or directory error:20074002:BIO routines:FILE_CTRL:system lib error:140DC002:SSL routines:SSL_CTX_use_certificate_chain_file:system lib)
This indicates Nginx cannot access the certificate file at the specified path, despite your confirmation that the file exists.
Let's verify several potential issues:
1. File Permissions
Check if Nginx has proper read permissions:
ls -l /path/to/cert.pem
You should see something like:
-rw-r--r-- 1 root root 1234 Jun 1 12:34 /path/to/cert.pem
If not, adjust permissions:
chmod 644 /path/to/cert.pem chown root:root /path/to/cert.pem
2. SELinux Context (For RHEL/CentOS)
Check and set proper context:
ls -Z /path/to/cert.pem chcon -t cert_t /path/to/cert.pem
3. Certificate Chain Format
Verify your merged certificate format is correct. A proper chain should look like:
-----BEGIN CERTIFICATE----- (Your domain certificate) -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- (Intermediate certificate) -----END CERTIFICATE-----
Here's a proper SSL configuration snippet:
server { listen 443 ssl; server_name example.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/private.key; # Other SSL settings... ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; # ... }
If the issue persists, try these steps:
1. Test with Absolute Path
Use the full absolute path in your Nginx config:
ssl_certificate /etc/nginx/ssl/cert.pem;
2. Verify File with OpenSSL
Check if OpenSSL can read the file:
openssl x509 -in /path/to/cert.pem -text -noout
3. Check Nginx Worker Process User
Ensure the Nginx worker user can access the file:
ps aux | grep nginx sudo -u www-data cat /path/to/cert.pem
- File exists at specified path
- Proper permissions (644)
- Correct ownership (root:root or nginx user)
- Valid certificate chain format
- No SELinux restrictions (or proper context)
- Using absolute path in configuration
When you encounter the error SSL_CTX_use_certificate_chain_file() failed
with a No such file or directory
message, Nginx is telling you it cannot locate or access your SSL certificate file despite your confidence in its existence. This typically points to one of several underlying issues we need to investigate.
Based on my experience administering hundreds of Nginx servers, here are the most frequent offenders:
1. Incorrect file permissions (nginx worker process can't read the file) 2. SELinux/AppArmor restrictions (common on RHEL/CentOS and Ubuntu) 3. Symbolic link resolution issues 4. Certificate chain formatting problems 5. Case sensitivity mismatches in paths
You mentioned merging domain.crt
and intermediate.crt
manually. Let me share the proper way to concatenate certificates:
# Correct merging order (your domain cert first): cat domain.crt intermediate.crt > cert.pem # Verify the certificate chain structure openssl crl2pkcs7 -nocrl -certfile cert.pem | openssl pkcs7 -print_certs -noout
A common mistake is including unnecessary blank lines between certificates or incorrect line endings. The file should use UNIX line endings (LF) and have exactly one blank line between certificates.
Run these commands to verify permissions (adjust paths as needed):
# Check file existence and permissions ls -l /path/to/cert.pem # Verify nginx worker user can access the file sudo -u nginx test -r /path/to/cert.pem && echo "Readable" || echo "Not readable" # Check parent directory permissions (often overlooked) namei -l /path/to/cert.pem
For systems with mandatory access controls:
# For SELinux (RHEL/CentOS): ls -Z /path/to/cert.pem sudo chcon -R -t cert_t /path/to/cert.pem # For AppArmor (Ubuntu/Debian): sudo aa-status | grep nginx
Add this to your nginx.conf for better debugging:
events {} http { error_log /var/log/nginx/ssl_error.log debug; server { listen 443 ssl; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location / { return 200 "SSL Test OK"; } } }
Then test with:
sudo nginx -t sudo tail -f /var/log/nginx/ssl_error.log
If the above doesn't resolve it, consider:
# 1. Try absolute path instead of relative: ssl_certificate /full/path/to/cert.pem; # 2. Verify file encoding: file /path/to/cert.pem # 3. Check for hidden characters: cat -A /path/to/cert.pem # 4. Test with a simple self-signed cert as control: openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /tmp/test.key -out /tmp/test.crt \ -subj "/CN=localhost"