OpenSSL Best Practices for Key Management and TLS Configuration

Troubleshooting Common OpenSSL Errors and FixesOpenSSL is a widely used toolkit for SSL/TLS and cryptographic functions. Because it interacts with certificates, keys, and network layers, errors are common — and can be frustrating. This article covers the most frequent OpenSSL errors, explains their causes, and provides step-by-step fixes and best practices to avoid them.


1) “unable to load certificate” / “unable to load private key”

Symptoms:

  • OpenSSL commands fail with messages like unable to load certificate or unable to load private key.
  • Tools that rely on the certificate (web servers, load balancers) refuse to start.

Causes:

  • Incorrect file path or permissions.
  • File in the wrong format (e.g., DER vs PEM).
  • Corrupted file or extra characters (line breaks, spaces).
  • Mismatched key and certificate.

Fixes:

  1. Verify path and permissions:
    • Ensure file exists and is readable by the process user.
    • Example:
      
      ls -l /etc/ssl/certs/example.crt chmod 644 /etc/ssl/certs/example.crt 
  2. Check format:
    • PEM files begin with —–BEGIN CERTIFICATE—–.
    • DER files are binary. Convert DER to PEM:
      
      openssl x509 -in cert.der -inform DER -out cert.pem -outform PEM 
  3. Inspect certificate and key:
    • View certificate:
      
      openssl x509 -in cert.pem -text -noout 
    • View private key:
      
      openssl pkey -in privkey.pem -text -noout 
  4. Confirm key and certificate match:
    • Compare modulus or public key fingerprints:
      
      openssl x509 -noout -modulus -in cert.pem | openssl md5 openssl rsa -noout -modulus -in privkey.pem | openssl md5 

      For modern keys:

      
      openssl pkey -in privkey.pem -pubout -outform pem | openssl rsa -pubin -pubout -text -noout openssl x509 -in cert.pem -pubkey -noout -outform pem | openssl pkey -pubin -pubout -text -noout 
  5. Remove extra text or corruption:
    • Open the file in a text editor and ensure clear BEGIN/END lines and base64 content.

2) “certificate has expired” / “self signed certificate in certificate chain”

Symptoms:

  • TLS clients report the certificate is expired or untrusted.
  • Browsers show warnings; command-line tools fail verification.

Causes:

  • Certificate’s validity period ended.
  • Using self-signed cert or missing intermediate CA certificates.

Fixes:

  1. Check expiration:
    
    openssl x509 -enddate -noout -in cert.pem 
  2. Renew certificate via your CA or reissue with proper dates.
  3. If self-signed or internal CA, ensure the client trusts the CA cert:
    • Add CA to trusted store or provide full chain to server:
      
      cat server.crt intermediate.crt > fullchain.pem 
  4. Verify full chain:
    
    openssl verify -CAfile ca-bundle.crt fullchain.pem 

3) “SSL routines:ssl3_get_server_certificate:certificate verify failed”

Symptoms:

  • Clients fail TLS handshake with verify errors.
  • Curl or browsers report inability to verify certificate chain.

Causes:

  • Missing or incorrect CA bundle on client.
  • Hostname mismatch between certificate CN/SAN and requested hostname.
  • Expired or untrusted certificate.

Fixes:

  1. Test with OpenSSL s_client to inspect chain and cert details:
    
    openssl s_client -connect example.com:443 -showcerts 

    Review certificate chain and subjectAltName.

  2. Check hostname in certificate:
    
    openssl x509 -in cert.pem -noout -subject -text | grep -A1 "Subject Alternative Name" 
  3. Point client to correct CA bundle:
    • With curl:
      
      curl --cacert /path/to/ca-bundle.crt https://example.com 
  4. For local testing only, you can skip verification (not recommended in production):
    
    openssl s_client -connect example.com:443 -servername example.com -verify 0 

4) “unsupported protocol” / “wrong version number”

Symptoms:

  • TLS connection fails with protocol errors.
  • Server and client fail to negotiate a common TLS version.

Causes:

  • Server or client configured to use incompatible TLS/SSL versions.
  • Old OpenSSL or server not supporting modern TLS1.⁄1.3.
  • Attempting SSLv3 or TLS 1.0 connections blocked by server or client policy.

Fixes:

  1. Check supported protocols on server with nmap or openssl:
    
    openssl s_client -connect example.com:443 -tls1_2 openssl s_client -connect example.com:443 -tls1_3 
  2. Update OpenSSL/server to support modern TLS versions.
  3. Configure server to allow appropriate protocols and ciphers (example for nginx):
    
    ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; 
  4. Ensure client explicitly requests a supported version if automatic negotiation fails.

5) “bad decrypt” / “unable to load encrypted private key”

Symptoms:

  • Error when reading an encrypted private key or during operations that require the key.
  • Prompts for passphrase repeatedly or shows “bad decrypt”.

Causes:

  • Wrong passphrase.
  • Key encrypted with an unsupported cipher or format.
  • Corrupted key file.

Fixes:

  1. Ensure correct passphrase. Try decrypting interactively:
    
    openssl rsa -in encrypted.key -check 
  2. Convert key to unencrypted PEM (only if secure to do so):
    
    openssl rsa -in encrypted.key -out decrypted.key 

    For modern private keys:

    
    openssl pkey -in encrypted.key -out decrypted.key 
  3. If key uses old DES-based encryption unsupported by current OpenSSL builds, convert on system with compatible OpenSSL or use compatible flags.
  4. Restore from backup if file corrupted.

6) “error:0A00018E:SSL routines::ca md too weak” / “digest algorithm too weak”

Symptoms:

  • OpenSSL rejects certificates or signatures citing weak hash algorithms (MD5, SHA1).

Causes:

  • Certificates or CRLs signed with deprecated hash algorithms.
  • Security policy in OpenSSL forbids weak digests.

Fixes:

  1. Check signature algorithm:
    
    openssl x509 -in cert.pem -noout -text | grep "Signature Algorithm" 
  2. Reissue certificate using SHA-256 or stronger.
  3. Temporarily lower security level (not recommended except for legacy environments):
    • Adjust OpenSSL config or set cipher/legacy options in application (example for OpenSSL client):
      
      openssl s_client -connect example.com:443 -sigalgs RSA+SHA1 
    • In OpenSSL config:
      
      CipherString = DEFAULT:@SECLEVEL=1 

7) “no start line” / “error:14090086:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib”

Symptoms:

  • OpenSSL reports PEM parsing errors like no start line or PEM lib.

Causes:

  • File missing the PEM header/footer or corrupted.
  • File contains extra text or combined different PEM types incorrectly.

Fixes:

  1. Open file and ensure header/footer are correct:
    • Certificates: —–BEGIN CERTIFICATE—– / —–END CERTIFICATE—–
    • Private keys: —–BEGIN PRIVATE KEY—– or —–BEGIN RSA PRIVATE KEY—– etc.
  2. Separate concatenated PEM files into correct components.
  3. Recreate or re-export the item from original source.

8) “WRONG_VERSION_NUMBER” from clients like curl

Symptoms:

  • Curl or other clients report SSL peer shut down incorrectly or wrong version number.

Causes:

  • Connecting to an HTTP service on an HTTPS port (or vice versa).
  • Proxy returning non-TLS response.
  • Protocol mismatch (e.g., connecting TLS to plain TCP).

Fixes:

  1. Verify port and protocol: ensure HTTPS is on 443 and server expects TLS.
  2. Use curl verbose to inspect response:
    
    curl -v https://example.com 
  3. Check for intercepting proxy or load balancer returning plaintext.

9) Performance or handshake slowness

Symptoms:

  • TLS handshakes take long or high CPU during handshake.

Causes:

  • Lack of session resumption (no session tickets or session IDs).
  • Expensive key exchange (RSA with very large keys or lack of ECDHE).
  • Entropy shortages on headless VMs (blocking on /dev/random).

Fixes:

  1. Enable ECDHE and session tickets/resumption on server.
  2. Use modern curves and reasonable key sizes (e.g., ECDSA P-256 / RSA 2048–4096).
  3. Ensure /dev/urandom used for non-blocking entropy or add rng-tools on VMs.

10) “unable to get local issuer certificate” when verifying chain

Symptoms:

  • Verification errors citing missing issuer or incomplete chain.

Causes:

  • Server not presenting intermediate CA certificates.
  • Client CA bundle missing intermediate issuer.

Fixes:

  1. Provide full chain from server:
    
    cat server.crt intermediate.crt > fullchain.pem 
  2. Verify chain:
    
    openssl verify -CAfile ca-bundle.crt fullchain.pem 
  3. Update client CA bundle if needed.

Debugging workflow checklist

  1. Reproduce the error with verbose output:
    • openssl s_client -connect host:port -showcerts -servername host
    • curl -v –cacert /path/to/ca-bundle.crt https://host
  2. Inspect certificate and key files:
    • openssl x509 -in cert.pem -text -noout
    • openssl pkey -in key.pem -text -noout
  3. Check key/certificate match and expiration.
  4. Verify chain with CA bundle.
  5. Confirm server configuration (nginx, Apache, HAProxy) has correct file ordering and permissions.
  6. If needed, increase OpenSSL verbosity or review application logs.

Best practices to avoid OpenSSL issues

  • Use PEM format consistently and keep backups of original keys/certs.
  • Automate certificate renewal (Let’s Encrypt, ACME clients).
  • Prefer modern TLS versions (TLS 1.2 and 1.3) and ECDHE key exchange.
  • Maintain an up-to-date CA bundle on clients and servers.
  • Store private keys securely and avoid keeping unencrypted keys on disk.
  • Test deployments with tools: openssl s_client, sslyze, testssl.sh, and online TLS checkers.

If you want, I can: provide command examples for your server (nginx/Apache), analyze specific certificate files you paste, or format a troubleshooting checklist tailored to your environment.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *