Explain Codes LogoExplain Codes Logo

How to fix the "java.security.cert.CertificateException: No subject alternative names present" error?

java
ssl-checks
certificate-exception
java-security
Alex KataevbyAlex Kataev·Feb 17, 2025
TLDR

Fix the CertificateException by updating your certificate with the appropriate Subject Alternative Names (SANs). A temporary resolution could be disabling the SAN check with:

System.setProperty("jdk.internal.httpclient.disableHostnameVerification", "true");

However, always strive to correct the certificate for security maintenance.

Resolving the underlying cause

The root cause of this problem is a mismatch between your server's certificate and the domain you're connecting to. Fix options:

  • Renew Certificate: Update the certificate with the correct SANs.
  • Verify DNS Entries: Make sure they match with the certificate's SANs.
  • Local Hosts File: For testing, add the server's FQDN to the local hosts file.

Remember, security matters

Bypassing SSL checks undeniably fixes the initial error but can compromise your app's security. It's exceptionally crucial to use such workarounds only for testing or development scenarios:

  • All-Trusting Managers: Avoid using in production! They accept all SSL certificates, enabling easy MITM attacks.
  • Verify JDK Versions: Different releases may handle certificates differently due to security upgrades.
  • OpenSSL Utility: An effective tool that can assist in diagnosing server certificates and analyzing SANs.

Need a quick fix?

In situations where you cannot modify certificate configurations quickly, consider these methods for development environments:

  • Custom SSL Context: Implement it in your client-side code.
  • Limited Trust Manager: Utilize for custom control over certificates.
  • Hostname Verifier: If dealing with IPs, use a custom verifier.
  • System Property Settings: sun.security.ssl.allowUnsafeRenegotiation can be used for immediate relief.

Implementing advanced configurations

Custom Hostname Verification

In urgent situations where you can't quickly update the certificate, a custom hostname verifier can be put to use:

// Remember when Mom said not to talk to strangers? Exceptions can be made. HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> return true)

Remember, not to let this verifier lonely too long!

Trust Management Control

To have power in your hands, use a custom TrustManager:

// The overly trusting manager who believes in everyone 😅 // But with great power, comes great responsibility. Don't misuse it! TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {} public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {} } }

Installation of Correct Certificate

Ensure that the server certificate is installed properly in Java's cacerts:

// Remember the "Sesame" trick? Well, the key to the default store is 'changeit'! keytool -import -alias <alias> -file <certificate_file> -keystore <path_to_cacerts> -storepass changeit

Ensure DNS SANs are right: Always cross-check if DNS SANs align to the expected domain or service your client is aiming to reach.