Nginx SSL Certificate Loading Error: Fixing “BIO_new_file() failed” When Certificate File Exists


2 views

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;
    }
}