The alert certificate required error means the client tried to initiate a TLS 1.3 handshake but the server didn’t present a certificate, which is mandatory for server authentication in TLS 1.3.

Here’s why that’s a problem: TLS 1.3 relies on the server proving its identity to the client using a digital certificate. Without it, the client can’t trust it’s talking to the legitimate server, hence the "certificate required" alert. This usually points to a misconfiguration on the server side or an issue with how the server is being managed.

Common Causes and Fixes:

  1. Missing Server Certificate Configuration: The most straightforward reason is that the server simply hasn’t been told where its certificate and private key are.

    • Diagnosis: Check your web server’s (e.g., Nginx, Apache) virtual host configuration for TLS/SSL directives. For Nginx, look for ssl_certificate and ssl_certificate_key. For Apache, check SSLCertificateFile and SSLCertificateKeyFile.
    • Fix: Ensure these directives point to valid, readable certificate and key files. For example, in Nginx:
      ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
      
      Make sure the files exist and the web server user has read permissions. This works because the server needs these files to cryptographically prove its identity to the client during the handshake.
    • Why it works: The server reads these files to obtain its public key and identity information, which it then sends to the client.
  2. Expired Certificate: Certificates have a validity period. If it’s expired, the server can’t use it.

    • Diagnosis: Use openssl x509 -in /path/to/your/certificate.pem -noout -dates to check the notBefore and notAfter dates. You can also check your certificate authority’s dashboard.
    • Fix: Renew your certificate. If you’re using Let’s Encrypt, this is often automated with certbot renew. After renewal, you’ll likely need to reload your web server’s configuration. For Nginx: sudo systemctl reload nginx. For Apache: sudo systemctl reload apache2. This works because a valid certificate is a fundamental requirement for a successful TLS handshake.
    • Why it works: A new, valid certificate replaces the expired one, allowing the server to present a trusted identity.
  3. Incorrect Certificate Chain (Intermediate Certificates Missing): The server might be presenting its own certificate, but not the full chain of trust back to a root Certificate Authority (CA).

    • Diagnosis: Use an online SSL checker tool (like SSL Labs) and look for "Chain issues: Incomplete". Alternatively, use openssl s_client -connect yourdomain.com:443 -servername yourdomain.com and examine the certificate chain presented.
    • Fix: Concatenate your server certificate, any intermediate certificates, and potentially the root certificate into a single file. For Let’s Encrypt, this is usually handled by fullchain.pem which should be used in ssl_certificate (Nginx) or SSLCertificateChainFile (Apache, though often combined with the main cert). Ensure your ssl_certificate directive points to the file containing the full chain. For example:
      ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
      
      This works because the client needs to verify the server’s certificate by tracing it back through a chain of trusted certificates to a root CA.
    • Why it works: Providing the complete chain allows the client’s browser or OS to verify the server’s identity against its trusted root CA store.
  4. Permissions Issues on Certificate/Key Files: The web server process might not have the necessary read permissions for the certificate or private key files.

    • Diagnosis: Check file permissions with ls -l /path/to/your/certificate.pem and ls -l /path/to/your/private.key. The user the web server runs as (e.g., www-data for Apache/Nginx on Debian/Ubuntu) needs read access.
    • Fix: Grant read permissions. For example, if Nginx runs as www-data:
      sudo chown www-data:www-data /etc/letsencrypt/live/yourdomain.com/fullchain.pem
      sudo chown www-data:www-data /etc/letsencrypt/live/yourdomain.com/privkey.pem
      sudo chmod 644 /etc/letsencrypt/live/yourdomain.com/fullchain.pem
      sudo chmod 600 /etc/letsencrypt/live/yourdomain.com/privkey.pem # Key should be more restricted
      sudo systemctl reload nginx
      
      This works because the web server process needs to access these files to load them into memory for the TLS handshake.
    • Why it works: Correct permissions allow the web server process to read the certificate and key files it needs to operate.
  5. Private Key Mismatch: The private key file specified does not match the public key within the certificate file.

    • Diagnosis: You can check this by comparing the modulus of the public key in the certificate and the private key.
      openssl x509 -noout -modulus -in /path/to/your/certificate.pem | openssl md5
      openssl rsa -noout -modulus -in /path/to/your/private.key | openssl md5
      
      The MD5 hashes should match.
    • Fix: Ensure that the ssl_certificate_key (Nginx) or SSLCertificateKeyFile (Apache) directive points to the correct private key file that corresponds to the certificate. If they don’t match, regenerate your certificate or locate the correct private key. Regenerating with Let’s Encrypt usually fixes this if you’ve lost track of keys: sudo certbot --nginx -d yourdomain.com.
    • Why it works: The private key is essential for the server to complete the TLS handshake, specifically for decrypting the client’s key exchange information and signing parts of the handshake. A mismatch means this cryptographic proof of identity fails.
  6. Wildcard Certificate Misconfiguration: If using a wildcard certificate (*.yourdomain.com), ensure the certificate is correctly configured to cover the specific hostname the client is trying to reach, and that the server is set up to use it for that hostname.

    • Diagnosis: Check the Subject Alternative Name (SAN) or Subject field of the certificate using openssl x509 -in /path/to/your/certificate.pem -noout -text | grep DNS:. Verify that the hostname the client is connecting to is listed. Also, check your server’s virtual host configuration to ensure the wildcard certificate is applied to the correct server block for that hostname.
    • Fix: If the hostname is not covered, obtain a new certificate that includes it or a broader wildcard. Ensure your server configuration correctly maps the hostname to the virtual host using the wildcard certificate. For Nginx, this means the server_name directive in the relevant server block should match or include the hostname.
    • Why it works: The server must present a certificate that the client’s requested hostname can cryptographically validate against.

If you fix all of these, the next error you’ll likely encounter is related to cipher suite negotiation or perhaps a certificate unknown error if the CA isn’t trusted by the client.

Want structured learning?

Take the full Tls-ssl course →