The Nginx worker process failed to establish a secure TLS connection with a peer because the peer unexpectedly terminated the handshake.

This usually happens because the peer doesn’t understand or doesn’t support the TLS cipher suites or protocol versions Nginx is offering, or because a firewall is interfering with the TLS negotiation.

Common Causes and Fixes

  1. Client TLS Version Mismatch: The client is trying to connect using an older TLS version (like TLSv1 or TLSv1.1) that Nginx has disabled for security reasons.

    • Diagnosis: Check your Nginx ssl_protocols directive. If it only lists TLSv1.2 TLSv1.3, clients on older versions will fail.
    • Fix: For maximum compatibility, you might temporarily add TLSv1.1 back, though this is discouraged for security. Edit your Nginx configuration (e.g., /etc/nginx/nginx.conf or a site-specific file in conf.d/ or sites-available/):
      ssl_protocols TLSv1.2 TLSv1.3 TLSv1.1;
      
      Then reload Nginx: sudo systemctl reload nginx.
    • Why it works: This explicitly allows Nginx to negotiate using TLSv1.1 if the client only supports it.
  2. Client Cipher Suite Mismatch: The client does not support any of the cipher suites Nginx is configured to use.

    • Diagnosis: Examine your ssl_ciphers directive. Modern Nginx configurations often use strong, modern cipher suites.
    • Fix: You may need to add more compatible cipher suites. A common, broader set includes:
      ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA';
      
      Add this to your Nginx configuration within the server block that uses SSL, and reload: sudo systemctl reload nginx.
    • Why it works: This expands the list of acceptable encryption algorithms, increasing the chance of finding a common one with the client.
  3. Intermediate Firewall/Proxy Interference: A network device between Nginx and the client is inspecting or modifying TLS traffic, causing the handshake to fail. This is particularly common with older, stateful firewalls.

    • Diagnosis: This is harder to diagnose directly. Try accessing Nginx from a client on the same network segment as the server, bypassing any intermediate firewalls. If it works there, a firewall is the likely culprit.
    • Fix: Consult your network administrator to either configure the firewall to allow the specific TLS traffic or to disable TLS inspection for this connection. There’s no Nginx configuration fix for this.
    • Why it works: Removing the interfering device allows the TLS handshake to complete without modification.
  4. Incorrect Certificate Chain: The client cannot validate the Nginx server’s certificate because it’s missing intermediate certificates, or the chain is malformed.

    • Diagnosis: Use openssl s_client -connect your_domain.com:443 -servername your_domain.com and check the verify return code. A code indicating an unknown certificate authority or a broken chain points to this.
    • Fix: Ensure your SSL certificate bundle includes the full chain. Concatenate your server certificate and all intermediate certificates into a single file, with the server certificate first, followed by the intermediates. For example, if your cert is domain.crt, intermediates are intermediate1.crt and intermediate2.crt:
      cat domain.crt intermediate1.crt intermediate2.crt > fullchain.pem
      
      Update your ssl_certificate directive in Nginx to point to fullchain.pem and reload: sudo systemctl reload nginx.
    • Why it works: Providing the complete chain allows the client’s TLS library to trace the certificate back to a trusted root CA.
  5. Client Server Name Indication (SNI) Issue: If Nginx hosts multiple SSL sites on the same IP address, and the client doesn’t send a valid Host header or SNI extension, Nginx might present the wrong certificate or fail the handshake.

    • Diagnosis: Check Nginx logs for messages related to SNI. The openssl s_client command (as above) will show the certificate presented. If it’s not the one expected for your_domain.com, SNI is likely the issue.
    • Fix: Ensure clients are sending a valid Host header and that Nginx is configured correctly for SNI. For older clients that don’t support SNI, you might need a default server block that listens on port 443 without SNI requirements and serves a generic certificate, or ensure your primary server block catches all un-SNI’d requests.
      server {
          listen 443 ssl default_server;
          server_name _; # Catches requests without a specific server_name or SNI
          ssl_certificate /etc/nginx/ssl/default.pem;
          ssl_certificate_key /etc/nginx/ssl/default.key;
          # ... other SSL settings, possibly a redirect or error page
      }
      
      Reload Nginx: sudo systemctl reload nginx.
    • Why it works: This provides a fallback certificate for clients that don’t specify a hostname via SNI, allowing the handshake to proceed.
  6. Outdated OpenSSL Library on Server: The Nginx server itself might be running an extremely old version of OpenSSL that has compatibility issues with modern clients or specific cipher suites.

    • Diagnosis: Check your Nginx version (nginx -v) and the OpenSSL version it’s linked against (openssl version). While Nginx might be recent, it could be compiled against an old OpenSSL.
    • Fix: Update Nginx and its OpenSSL dependencies to current stable versions. This typically involves using your distribution’s package manager (e.g., sudo apt update && sudo apt upgrade nginx openssl on Debian/Ubuntu, or sudo yum update nginx openssl on CentOS/RHEL).
    • Why it works: Newer OpenSSL libraries support a wider range of modern TLS features and cipher suites, improving compatibility.

After fixing these, the next error you’ll likely encounter is a "502 Bad Gateway" if your Nginx is acting as a reverse proxy and the upstream application server is having issues.

Want structured learning?

Take the full Nginx course →