Nginx SSL Certificate Errors: PEM_read_bio_X509_AUX, PEM_read_bio_X509, SSL_CTX_use_PrivateKey_file

Want to help support this blog? Try out Oh Dear, the best all-in-one monitoring tool for your entire website, co-founded by me (the guy that wrote this blogpost). Start with a 10-day trial, no strings attached.

We offer uptime monitoring, SSL checks, broken links checking, performance & cronjob monitoring, branded status pages & so much more. Try us out today!

Profile image of Mattias Geniar

Mattias Geniar, August 13, 2015

Follow me on Twitter as @mattiasgeniar

When configuring your SSL certificates on Nginx, it’s not uncommon to see several errors when you try to reload your Nginx configuration, to activate the SSL Certificates.

This post describes the following type of errors:

Read on for more details.

Nginx PEM_read_bio_X509: ASN1_CHECK_TLEN:wrong tag error

These kind of errors pop up when your certificate file isn’t valid. The entire error looks like this.

$ service nginx restart

nginx: [emerg] PEM_read_bio_X509("/etc/nginx/ssl/mydomain.tld/certificate.crt") failed (SSL: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:Type=X509_CINF error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:Field=cert_info, Type=X509 error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib)

You should fix this by beginning to read the SSL certificate info via the CLI. Chances are, OpenSSL will also show you an error, to confirm your SSL certificate isn’t valid.

In the example above, the SSL certificate is in /etc/nginx/ssl/mydomain.tld/certificate.crt, so the following examples continue to use that file.

$ openssl x509 -text -noout -in /etc/nginx/ssl/mydomain.tld/certificate.crt
unable to load certificate
139894337988424:error:0906D064:PEM routines:PEM_read_bio:bad base64 decode:pem_lib.c:818:

If that’s your output, you have confirmation: your SSL certificate is corrupt. It’s got unsupported ASCII characters, it’s missing a part, some copy/paste error caused extra data to be present, … Bottom line: your certificate file won’t work.

You can test a few things yourself, like new line issues (linux vs. windows remains a problem). Open the file in binary mode in vi, and if you see ^M at end of every line, you’ve incorrectly got Windows new lines instead of Unix new lines.

$ vi -b /etc/nginx/ssl/mydomain.tld/certificate.crt
-----BEGIN CERTIFICATE-----^M
MIIFUjCCBDqgAwIBAgIKYsvzdQAAAAAAzTANBgkqhkiG9w0BAQUFADBOMQswCQYD^M
...

Remove all new lines and replace them with “normal” unix new lines (\n instead of \r\n).

If your SSL certificate file contains multiple certificates, like intermediate or CA root certificates, it’s important to check each of them separately. You can check this by counting the "-—-BEGIN CERTIFICATE-—-" lines in the file.

If you’ve got multiple certificates, copy/paste each one to a different file and run the openssl example above. Each should give you valid output from the SSL certificate.

$ grep 'BEGIN CERTIFICATE' /etc/nginx/ssl/mydomain.tld/certificate.crt
-----BEGIN CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-----BEGIN CERTIFICATE-----

The output above shows that the SSL Certificate file contains 3 individual SSL certificates. Copy/paste them all in separate files and validate if they work. If one of them gives you errors, fix that one: find the wrong ASCII characters, fix the new lines, check if you copy/pasted it correctly from your vendor, …

The “nginx: [emerg] PEM_read_bio_X509” error means your Nginx configuration is probably correct, it’s the SSL certificate file itself that is invalid.

Nginx PEM_read_bio_X509_AUX: Expecting: TRUSTED CERTIFICATE

This is an error that is usually resolved very quickly. The certificate file you’re pointing your config to, isn’t a certificate file. At least, not according to Nginx.

$ service nginx configtest

nginx: [emerg] PEM_read_bio_X509_AUX("/etc/nginx/ssl/mydomain.tld/certificate.crt") failed (SSL: error:0906D06C:PEM routines:PEM_read_bio:no start line:Expecting: TRUSTED CERTIFICATE)
nginx: configuration file /etc/nginx/nginx.conf test failed

This can happen if you’ve accidentally swapped your private key and SSL certificate in either your files, or in the Nginx configuration.

Your Nginx config will contain these kind of lines for its SSL configuration.

ssl_certificate             /etc/nginx/ssl/mydomain.tld/certificate.crt;
ssl_certificate_key         /etc/nginx/ssl/mydomain.tld/certificate.key;

Check if the ssl_certificate file is indeed your SSL certificate and if the ssl_certificate_key is indeed your key. It’s not uncommon to mix these up if you’re in a hurry or distracted and save the wrong contents to the wrong file.

Nginx SSL_CTX_use_PrivateKey_file: bad base64 decode error

Another common error in Nginx configurations is the following one.

$ service nginx configtest

nginx: [emerg] SSL_CTX_use_PrivateKey_file("/etc/nginx/ssl/mydomain.tld/certificate.key") failed (SSL: error:0906D064:PEM routines:PEM_read_bio:bad base64 decode error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib)
nginx: configuration file /etc/nginx/nginx.conf test failed

Note how the Nginx SSL error points to the .key file this time. The problem is with the SSL key, not the SSL certificate.

This error indicates that the private key you pointed your configuration to, doesn’t match the SSL Certificate.

You can validate whether private key and SSL certificate match by calculating their MD5 hash. If they don’t match, you have to find either the right certificate or the right private key file.

One of them is wrong and needs to be replaced. With this error, it’s impossible to know which one is wrong. Your best bet is to read the info from the SSL certificate, determine if that’s the correct SSL certificate (check expiration date, SANs, Common Name, …), and find the matching key (which should have been created when you generated your Certificate Signing Request, CSR).



Want to subscribe to the cron.weekly newsletter?

I write a weekly-ish newsletter on Linux, open source & webdevelopment called cron.weekly.

It features the latest news, guides & tutorials and new open source projects. You can sign up via email below.

No spam. Just some good, practical Linux & open source content.