If Nginx cannot read your SSL certificate file

in SEO & Webmaster


I got my Letsencrypt SSL certificate and wanted to configure Nginx to use it.

I added listen 443 ssl and pointed ssl_certificate and ssl_certificate_key to the right files, using $server_name variable.

listen 443 ssl;
ssl_certificate /usr/local/etc/letsencrypt/live/$server_name/fullchain.pem;
ssl_certificate_key /usr/local/etc/letsencrypt/live/$server_name/privkey.pem;

The above didn't work, giving me these cryptic errors:

  • SSL_ERROR_INTERNAL_ERROR_ALERT in Firefox
  • ERR_SSL_PROTOCOL_ERROR in Chrome

Here's what to watch out for

  1. Make sure you got the path right. To debug, you can use add_header on a working port 80 server {}.

    add_header X-Debug-Fullchain "/usr/local/etc/letsencrypt/live/$server_name/fullchain.pem";
  2. Check /var/log/nginx/error.log, it will most likely tell you what the problem is.

  3. If your problem is the permissions:

    [error] 57165#100839: *2 cannot load certificate "/usr/local/etc/letsencrypt/live/example.com/fullchain.pem": BIO_new_file() failed (SSL: error:8000000D:system library::Permission denied:calling fopen(/usr/local/etc/letsencrypt/live/example.com/fullchain.pem, r) error:10080002:BIO routines::system lib) while SSL handshaking

    ...make sure that nginx user (most often www on FreeBSD, www-data on Linux) can access not only the actual certificate files, but also the certificate folder (/usr/local/etc/letsencrypt on FreeBSD, /etc/letsencrypt on Linux) Bonus points: having the directory permissions right is especially important if using $server_name variable in the certificate path. This has to do with how nginx does virtual server selection in advance during SSL handshake.

Finally, remember that the actual, final certificate files are located in etc/letsencrypt/archive, and what you see elsewhere is most likely symliks to the archive files. To check, do readlink -f /usr/local/etc/letsencrypt/live/example.com/fullchain.pem.

Sources and further reading:

#ssl #nginx