When configuring SSL for Nginx, you might encounter this frustrating error despite having the certificate files in place:
BIO_new_file("/etc/gninx/ssl/server.crt") failed
(SSL: error:02001002:system library:fopen:No such file or directory:
fopen('/etc/gninx/ssl/server.crt','r')
error:2006D080:BIO routines:BIO_new_file:no such file)
The key observation here is the path typo in the error message: /etc/gninx/ssl/server.crt
versus the actual directory /etc/nginx/ssl
. There's a clear mismatch in your Nginx configuration:
ssl_certificate /etc/gninx/ssl/server.crt; # Typo here: "gninx"
ssl_certificate_key /etc/nginx/ssl/server.key; # Correct path here
First, verify your actual SSL file locations:
ls -l /etc/nginx/ssl/
total 12
-rwx------ 1 root root 1346 Aug 3 14:36 server.crt
-rwx------ 1 root root 1115 Aug 3 14:36 server.csr
-rwx------ 1 root root 1743 Aug 3 14:35 server.key
Then fix the configuration file by correcting the path:
server {
listen 443 ssl; # Modern syntax combines listen and ssl
server_name localhost;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
# ... rest of your configuration
}
After fixing the path, perform these checks:
# Test configuration syntax
nginx -t
# Verify file readability
sudo -u nginx test -r /etc/nginx/ssl/server.crt || echo "Read permission issue"
# Check SELinux context if applicable
ls -Z /etc/nginx/ssl/
For reference, here's a robust SSL configuration:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
location / {
# Your application configuration
}
}
Ensure proper permissions for Nginx to access the files:
chmod 640 /etc/nginx/ssl/server.{crt,key}
chown root:nginx /etc/nginx/ssl/server.{crt,key}
The most immediate issue in your configuration is a simple but critical typo:
ssl_certificate /etc/gninx/ssl/server.crt; # Note the misspelled "gninx"
ssl_certificate_key /etc/nginx/ssl/server.key; # Correct "nginx" spelling
When Nginx attempts to load your SSL certificate, it's looking for the file at:
/etc/gninx/ssl/server.crt
But your actual directory is:
/etc/nginx/ssl/server.crt
In UNIX systems, this creates a "silent" failure because:
- The error message shows the exact path it attempted
- No automatic path correction exists
- Permissions are checked after path resolution
Here's a verified working configuration example:
server {
listen 443 ssl;
server_name example.com;
# Corrected paths
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
# Recommended SSL parameters
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
... rest of your config ...
}
Even after fixing the path, you might encounter permission problems. Verify with:
sudo namei -l /etc/nginx/ssl/server.crt
Sample output should show at least -r--------
(400) permissions:
f: /etc/nginx/ssl/server.crt
drwxr-xr-x root root /
drwxr-xr-x root root etc
drwxr-xr-x root root nginx
drwx------ root root ssl
-r-------- root root server.crt
If issues persist, try these diagnostic commands:
# Check if Nginx can actually read the file
sudo -u nginx test -r /etc/nginx/ssl/server.crt && echo "Readable" || echo "Not readable"
# Validate certificate chain
openssl x509 -in /etc/nginx/ssl/server.crt -text -noout
# Verify key matches certificate
openssl x509 -noout -modulus -in /etc/nginx/ssl/server.crt | openssl md5
openssl rsa -noout -modulus -in /etc/nginx/ssl/server.key | openssl md5
# Both should output the same hash
Here's a fully functional minimal SSL configuration:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
location / {
root /var/www/html;
index index.html;
}
}