Ошибка javax net ssl sslhandshakeexception

Whenever we are trying to connect to URL,

if server at the other site is running on https protocol and is mandating that we should communicate via information provided in certificate then
we have following option:

1) ask for the certificate(download the certificate), import this certificate in trustore. Default trustore java uses can be found in Javajdk1.6.0_29jrelibsecuritycacerts, then if we retry to connect to the URL connection would be accepted.

2) In normal business cases, we might be connecting to internal URLS in organizations and we know that they are correct.
In such cases, you trust that it is the correct URL, In such cases above, code can be used which will not mandate to store the certificate to connect to particular URL.

for the point no 2 we have to follow below steps :

1) write below method which sets HostnameVerifier for HttpsURLConnection which returns true for all cases meaning we are trusting the trustStore.

  // trusting all certificate 
 public void doTrustToCertificates() throws Exception {
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                        return;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                        return;
                    }
                }
        };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) {
                    System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'.");
                }
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }

2) write below method, which calls doTrustToCertificates before trying to connect to URL

    // connecting to URL
    public void connectToUrl(){
     doTrustToCertificates();//  
     URL url = new URL("https://www.example.com");
     HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 
     System.out.println("ResponseCode ="+conn.getResponseCode());
   }

This call will return response code = 200 means connection is successful.

For more detail and sample example you can refer to URL.

If you’re encountering the “handshake_failure through SSLHandshakeException” error, it means there is an issue with the SSL/TLS handshake between the client and server. This can be caused by a variety of reasons such as outdated SSL/TLS protocol version, missing SSL/TLS certificates, or incorrect SSL/TLS configurations.

To connect securely to a server, you first need to get the server’s public certificate. Save the certificate in a file and add it to your computer’s list of trusted certificates.

This list of trusted certificates is called the trust store and is located in a file called cacerts. You can find it in a folder named security in the Java installation directory.

To add the certificate to the trust store, you need to run a program called keytool with the certificate file, a meaningful name, and the path to the cacerts file.

keytool -import -file <the cert file> -alias <some meaningful name> -keystore <path to cacerts file>

Once you have completed these steps, you can communicate securely with the server provided that both JVMs (client/server) are using the following properties with the correct values:

java -Djavax.net.ssl.keyStore=path_to_keystore_file 
     -Djavax.net.ssl.keyStorePassword=password 
     -Djavax.net.ssl.trustStore=path_to_truststore_file 
     -Djavax.net.ssl.trustStorePassword=password MyClass

If you have followed the above steps and you are facing javax.net.ssl.SSLHandshakeException then you need to check for some possible causes.

Causes of the Issue

Here are some possible solutions to fix the issue javax.net.ssl.SSLHandshakeException:

  1. You need to update your SSL/TLS protocol version: Make sure that you’re using the latest SSL/TLS protocol version that is supported by your web server. Some older versions of SSL/TLS are no longer considered secure and may result in handshake failures. Consider upgrading to TLS 1.2 or TLS 1.3, which are currently the most secure versions.
  2. You need to install SSL/TLS certificates: Ensure that you have a valid SSL/TLS certificate installed on your web server. This certificate should be issued by a trusted certificate authority (CA) and should be valid for the domain name that you’re accessing. You can use online tools like SSL Checker to verify the validity of your SSL/TLS certificate.
  3. Wrong SSL/TLS configuration: Ensure that your SSL/TLS configuration is correct and matches the settings of your SSL/TLS certificate. If you’re using a self-signed certificate, make sure that you’ve installed it on your client device as well. If you’re unsure about your SSL/TLS configuration, you can use online tools like SSL Labs to diagnose any issues.
  4. Disable outdated SSL/TLS protocols: Disable outdated SSL/TLS protocols like SSLv3 or TLS 1.0/1.1 that are no longer considered secure. This will help prevent handshake failures and improve the security of your website. You can do this by modifying your web server configuration.
  5. Disable cipher suites with weak encryption: Disable cipher suites with weak encryption that are no longer considered secure. This will help prevent handshake failures and improve the security of your website. You can do this by modifying your web server configuration.

Troubleshooting and solution

When you set the system property javax.net.debug=ssl,handshake, it enables debug logging for SSL/TLS connections, including detailed information about the handshake process. This debug logging can help you determine whether a handshake failure is caused by the client or the server.:

 javax.net.debug=ssl,handshake

Another option is to use JInfo to see SSL/TLS Properties of the Java process

The jinfo command allows to view the system properties of the process. For example, if the PID of your process is 12345, you can use the following command to view the system properties:

jinfo -sysprops 12345

This will output a list of all system properties set for your Java process, including the value of javax.net.ssl.trustStore.

Look for the javax.net.ssl.trustStore property in the output and verify that it’s set to the expected value. For example, if you expect the trustStore to be set to /path/to/truststore, look for a line in the output that looks like this:

javax.net.ssl.trustStore=/path/to/truststore

By using the jinfo command to verify the runtime system properties, you can ensure that your Java application or server is using the correct SSL/TLS trustStore at runtime.

Finally, you can try to reproduce the SSLHandshakeException locally programmatically. This can be useful, for example, if your Client application uses unsupported Cipher suites. By enabling them in your code, you can determine if that is the root cause.

Here is a sample Java Class you can use to test SSL Connectivity:

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

public class SSLConnectivityTest {

    public static void main(String[] args) throws Exception {

        // Set the SSL socket factory
        SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();

        // Set the SSL socket
        SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket("your.server.com", 443);

        // Enable all supported cipher suites
        String[] enabledCipherSuites = sslSocket.getSupportedCipherSuites();
        sslSocket.setEnabledCipherSuites(enabledCipherSuites);

        // Start the SSL handshake
        sslSocket.startHandshake();

        // Get the input and output streams of the SSL socket
        InputStream inputStream = sslSocket.getInputStream();
        OutputStream outputStream = sslSocket.getOutputStream();

        // Write data to the SSL socket
        outputStream.write("Hello, server!n".getBytes());

        // Read data from the SSL socket
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line = reader.readLine();
        System.out.println("Server response: " + line);

        // Close the SSL socket
        sslSocket.close();
    }
}

Make sure you are running the above class with the KeyStore/TrustStore System Properties:

java -Djavax.net.ssl.keyStore=path_to_keystore_file -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=path_to_truststore_file -Djavax.net.ssl.trustStorePassword=password SSLConnectivityTest

Using OpenSSL to rest a remote connection

Besides, you can also use openssl as Client to debug the remote connection to a secure Host. For example:

openssl s_client -debug -connect www.server.com:443

You can use the openssl tool to verify some use cases, such as if your Java Client is not sending the SNI (service Name Indication) extension to a SSL/TLS endpoint. You can add the SNI to the openssl tool to verify if this solves the issue as follows:

openssl s_client -debug -connect www.server.com:443 -servername www.server.com

  1. SSL Handshakes in Java
  2. Fix the SSLHandshakeException Because of Missing Server Certificate
  3. Fix the SSLHandShakeException Because of Untrusted Server Certificate
  4. Fix the SSLHandShakeException Because of Incorrect Certificate
  5. Fix the SSLHandShakeException Because of Incompatible SSL Version and Cipher Suite

Fix the Javax.Net.SSL.SSLHandshakeException Error

This tutorial demonstrates the javax.net.ssl.SSLHandshakeException error in Java.

SSL Handshakes in Java

The SSL Handshakes are used for the client and server to establish trust and logistics required to secure the connection over the internet. There are typical steps in SSL Handshake operations which are needed to be followed:

  1. First, the client will provide the list of all possible cipher suites and SSL versions.
  2. The server will then agree on the particular cipher suite and SSL version, which will respond with a certificate.
  3. Then, the client will extract the public key from the given certificate and respond with the new encrypted pre-master key.
  4. Then, the server will use the private key to decrypt the pre-master key.
  5. Then, the client and server will compute the shared secret using the pre-master key together.
  6. Finally, the client and server will exchange messages which confirm the successful encryption and decryption of the shared secret.

The SSL Handshakes have two types. The first is the one-way SSL, which leaves the server to trust all the clients, and the second is the two-way SSL in which the client and server must accept each other’s certificates.

After understanding the SSL Handshakes, we can now discuss the SSLHandShakeException in detail. There are two scenarios of SSLHandShakeException, which are given below.

Fix the SSLHandshakeException Because of Missing Server Certificate

If an SSL Handshake operation when the client is connecting to the server did not receive any certificate, it would throw the SSLHandShakeException as mentioned below:

Exception in thread "main" javax.net.ssl.SSLHandshakeException:
  Received fatal alert: handshake_failure

To solve this issue, make sure you follow all the steps above. This problem occurs when the Keystore or the system properties are not entered properly.

Keystores are the certificates provided by the authorities, or we can also create our Keystores by using the keytool functionality of JDK. Here is an example for the Keystore:

$ keytool -genkey -keypass password 
                  -storepass password 
                  -keystore Server_Keystore.jks

The above keytool code is written in the Keystore file. Now the keytool can be used to extract a public certificate from the Keystore file which was generated above:

$ keytool -export -storepass password 
                  -file NewServer.cer 
                  -keystore Server_Keystore.jks

The above code will export the public certificate from the Keystore as a file NewServer.cer. Now, we can add it to the Truststore for the client:

$ keytool -import -v -trustcacerts 
                     -file NewServer.cer 
                     -keypass password 
                     -storepass password 
                     -keystore Client_Truststore.jks

Now the Keystore for the server and Truststore for the client are generated. We can pass them as system properties to the server with a command:

-Djavax.net.ssl.keyStore=Client_Keystore.jks -Djavax.net.ssl.keyStorePassword=password

It is necessary for the system property. The Keystore file path must be absolute or place the Keystore file in the same directory from where the command is invoked.

The relative paths are not supported. Once you follow this process, the missing certificate error will be solved, and there will be no more SSLHandShakeException.

Fix the SSLHandShakeException Because of Untrusted Server Certificate

The other reason for SSLHandShakeException is an untrusted server certificate. When a server is using a self-signed certificate that is not signed by authorities, it will throw the following error:

Exception in thread "main" javax.net.ssl.SSLHandshakeException:
  sun.security.validator.ValidatorException:
  PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
  unable to find valid certification path to requested target

This exception will be thrown whenever the certificate is signed by any entity other than the default store. The default Truststore in JDK ships the information about common certificates in use.

This issue can be solved by forcing the client to trust the certificate presented by the server. We need to use the Truststore we generated above and pass them as system properties to the client:

-Djavax.net.ssl.trustStore=Client_Truststore.jks -Djavax.net.ssl.trustStorePassword=password

This will solve the exception, but it is not an ideal situation. In an ideal situation, we can use the self-signed certificate, which should be certified by the Certificate Authority (CA), then the client can trust them by default.

Fix the SSLHandShakeException Because of Incorrect Certificate

A handshake can also fail because of an incorrect certificate. When a certificate is not created properly, it will throw the SSLHandShakeException:

Exception in thread "main" javax.net.ssl.SSLHandshakeException:
    java.security.cert.CertificateException:
    No name matching localhost found

To check if the certificate is created properly, run the following command:

keytool -v -list -keystore Server_Keystore.jks

The above command will show the details of the Keystore owner:

...
Owner: CN=localhost, OU=technology, O=delftstack, L=city, ST=state, C=xx
..

The owner’s CN must match the server’s CN, and if it doesn’t match, it will throw the same exception shown above as it is generated because of the different CN.

Fix the SSLHandShakeException Because of Incompatible SSL Version and Cipher Suite

While an SSL handshake operation, it is possible that there will be various cryptographic protocols like different versions of SSL, TLS, etc. While the client and server must agree on cryptographic protocols and versions on a handshake, the SSL is superseded by the TLS for its cryptographic strength.

Now, for example, if the server is using the protocol SSL3, and the client is using the protocol TLS1.3, both cannot agree on the cryptographic protocol, and it will throw the SSLHandShakeException:

Exception in thread "main" javax.net.ssl.SSLHandshakeException:
  No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

To solve this issue, we must verify that client and server are using either the same or compatible cryptographic protocols.

Similarly, it is also necessary to have the compatible Cipher Suite. While a handshake, the client provides the list of ciphers, and the server will select a cipher to use.

If the server cannot select a suitable cipher, the code will throw the following SSLHandShakeException:

Exception in thread "main" javax.net.ssl.SSLHandshakeException:
  Received fatal alert: handshake_failure

Normally the client and server use a variety of cipher suites; that is why this error can occur. The error occurs because a server has chosen a very selective cipher.

To avoid this issue, the server uses a list of selective ciphers, which is also good for security.

Due to Java security policy, the usage of TLS 1.0 and TLS 1.1 protocols was disabled. This Java update caused the javax.net.ssl.SSLHandshakeException error that occurred when you tried to connect to old servers that still accept these protocols.

As a fix, you can explicitly enable these protocols. Note that it might result in vulnerability issues. Consider using newer versions of TLS.

MySQL

  1. Open data source properties. You can open data source properties by using one of the following options:

    • Navigate to .

    • Press Ctrl+Alt+Shift+S.

    • In the Database Explorer ( ), click the Data Source Properties icon The Data Source Properties icon.

  2. Select a data source for which you want to enable disabled algorithms (for example, MySQL 8.0.3). The following required algorithms might be disabled: SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, include jdk.disabled.namedCurves.

  3. In the right pane of a data source, click Test Connection.

  4. In the notification, select an action that you want to perform. You can select among the following actions:

    • Edit disabled algorithms: opens the Advanced tab of the selected data source and moves the focus to the VM options field. In the VM options field, you can edit a list of disabled algorithms manually (for the Djdk.tls.disabledAlgorithms option).

    • Enable TLSv1: removes TLSv1 from the Djdk.tls.disabledAlgorithms option. This action will enable TLS 1.0.

    • Enable TLSv1.1: removes TLSv1.1 from the Djdk.tls.disabledAlgorithms option. This action will enable TLS 1.1.

    • Enable all protocols in JDBC driver: removes SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, include jdk.disabled.namedCurves from the Djdk.tls.disabledAlgorithms option. This action enables all the disabled algorithms.

  5. Click Test Connection and see if the fix works.

    You can try Enable TLSv1 and Enable TLSv1.1 first. If the error still occurs, try to enable other algorithms.

    javax.net.ssl.SSLHandshakeException

Microsoft SQL Server

  1. In a file browser, create a custom.java.security file with the following contents:

    jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA,
    DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL,
    include jdk.disabled.namedCurves

    Note that TLSv1 is removed from the list of disabled algorithms.

  2. Open data source properties. You can open data source properties by using one of the following options:

    • Navigate to .

    • Press Ctrl+Alt+Shift+S.

    • In the Database Explorer ( ), click the Data Source Properties icon The Data Source Properties icon.

  3. Select your Microsoft SQL Server data source and click the Advanced tab and add the following option to the VM options field: -Djava.security.properties=${PATH_TO_FILE?}/custom.java.security, where ${PATH_TO_FILE?} is a path to the created custom.java.security file.

  4. From the main menu, select .

  5. Try to connect to your Microsoft SQL Server data source.

    custom.java.security

Last modified: 05 December 2022

Disclosure: This article may contain affiliate links. When you purchase, we may earn a small commission.

If you are working in a Java web or enterprise application that connects to any other web server using HTTPS you might have seen the «javax.net.ssl.SSLHandshakeException». This is one of the particular cases of that error. If you know how SSL and HTTPS work that when a Java client connects to a Java server the SSL handshake happens. In these steps server return certificates to confirm its identity, which the client validates against the root certificate he has in its truststore. If Server returns a certificate that cannot be validated against the certificates a browser or Java client holds in its truststore then it throws the «sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target».

In other words, while connecting to any website or server using SSL or HTTPS in Java, sometimes you may face a problem of «unable to find valid certification path to requested target» exception  as shown below:


javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

The reason of this error is simple, certificates returned by the Server during SSL handshake are not signed by any trusted Certification Authority(CA) which are configured in your JRE’s truststore e.g Verisign, Thwate, GoDaddy, or Entrust etc.

Instead, the Server is sending a certificate that is unknown to JRE and that’s why it’s not able to validate those certifications against the private key he holds in his truststore.

If you remember, there is a subtle difference between keystore and truststore in Java. Even though, both stores certificates, keystore is used to store your credential (server or client) while truststore is used to store other credentials (Certificates from CA).

This could also happen when Server is sending certificate from other certificate authority which is not configured in JRE’s truststore i.e. some internal certificate signed by your company.

I got the exactly same error while connecting to our LDAP server using SSL from my Spring Security based Java web application. Since LDAP server was internal to the company, it was sending internally signed certificates which were not present in the Tomcat’s JRE (Java Runtime Environment).

To solve this problem you need to add certificates returned by the Server into your JRE’s truststore, which you can do by using keytool or other tools provided by your company.

How did I solved this Problem?

Nothing fancy, I use an open source program called InstallCert.java to add certificates returned by the Server into my JRE’s truststore. I just ran this program against our LDAP server and port. When it first tried to connect LDAP server using SSL it threw same «PKIX path building failed» error and then prints certificates returned by LDAP server. It will then ask you to add Certificate into keystore just give certificate number as appeared on your screen and it will then add those certificate into «jssecacerts» inside C:Program FilesJavajdk1.6.0jrelibsecurity folder. Now re-run the program that error should be disappeared and it will print:

«Loading KeyStore jssecacerts…
Opening connection to stockmarket.com:636…
Starting SSL handshake…
No errors, certificate is already trusted

You are done, now if you try authenticating against same LDAP server you will succeed. You can also configure the path of the JRE used by your application e.g. if you are running your application inside Tomcat, then you must give the path to the JRE used by Tomcat. You also need to configure HTTPS in Tomcat, which you do by following steps given here.

Here is also a nice diagram which tells what exactly happens when a Java client connect to Java server using https or SSL i.e during SSL handshake:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

By the way, this is not the only way to add certificates into the truststore. You can also use the keytool to add certificates into trust store as well. The keytool comes with JDK installation and you can find it inside the bind directory of JAVA_HOME.

This solution is particularly useful when you don’t have the certificates used by Server. If you can contact your infra guys or Linux admin to get certificates then you can use keytool to add those into truststore as shown below:

$ keytool -import -alias -ca -file /tmp/root_cert.cer -keystore cacerts

You can see here for some more examples of using keytool command in Java e.g. listing all certificates it has currently etc.

  • Ошибка javascript при запуске компьютера
  • Ошибка javascript error occurred in the main process discord
  • Ошибка java при установке faceit
  • Ошибка java при запуске minecraft
  • Ошибка java недостаточно памяти