javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:953)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1301)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
at br.com.onebr.onesocial.arte1.service.core.scheduler.Arte1XMLHandlerTest.testRetrieveSchedule(Arte1XMLHandlerTest.java:16)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
at sun.security.ssl.InputRecord.read(InputRecord.java:482)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934)
... 32 more
I got successful response from https://google.com but this error from URL above (https://ancine.band.com.br/xml/pgrt1_dta_20150303.xml).
Using PHP, .NET and NodeJS that URL works fine.
Anyone has any idea why this happening?
–
That is a problem of security protocol. I am using TLSv1 but the host accept only TLSv1.1 and TLSv1.2 then I changed the protocol in Java with the instruction below:
System.setProperty("https.protocols", "TLSv1.1")
;
Apart from the accepted answer, other problems can cause the exception too. For me it was that the certificate was not trusted (i.e., self-signed cert and not in the trust store).
If the certificate file does not exists, or could not be loaded (e.g., typo in path) can---in certain circumstances---cause the same exception.
–
–
–
As @Zigri2612 suggested, what worked for me was to add TLS https.protocols
, but i had to do it with white spaces instead of comma separated values:
System.setProperty("https.protocols", "TLSv1 TLSv1.1 TLSv1.2 TLSv1.3");
This error is generic of the security libraries and might happen in other cases.
In case other people have this same error when sending emails with javax.mail to a smtp server. Then the code to force other protocol is setting a property like this:
prop.put("mail.smtp.ssl.protocols", "TLSv1.2");
//And just in case probably you need to set these too
prop.put("mail.smtp.starttls.enable", true);
prop.put("mail.smtp.ssl.trust", {YOURSERVERNAME});
I've encountered the same error message but the reason and solution are quite interesting:
my problem resolved by upgrading the openjdk from 8u40 to 8u191 or higher version 8u312,
the root cause is a kind of interoperability issue that seems the client and server are using different padding method or cipher parameter(e.g EC curve) for DH key exchange,
so if you run out of solutions, probably you may try upgrade your jdk(don't just upgrade to a major version, try to upgrade to a higher minor version first, please note my problem resolved by higher minor version for openjdk8uXXX but still failed with openjdk9)
you may refer to the whole troubleshooting process at(handshake section):
https://lyhistory.github.io/docs/software/network/layer4_http_ssl_tls_setup.html
–
The accepted answer didn't work in my situation, not sure why. I switched from JRE1.7 to JRE1.8 and that resolved the issue automatically.
JRE1.8 uses TLS1.2 by default
I was having the same issue, as everyone else I suppose.. adding the System.setProperties(....) didn't fix it for me.
So my email client is in a separate project uploaded to an artifactory. I'm importing this project into other projects as a gradle dependency. My problem was that I was using implementation
in my build.gradle for javax.mail
, which was causing issues downstream.
I changed this line from implementation
to api
and my downstream project started working and connecting again.
I had mutual SSL enabled on my Spring Boot app and my Jenkins pipeline was re-building the dockers, bringing the compose up and then running integration tests which failed every time with this error.
I was able to test the running dockers without this SSL error every time in a standalone test on the same Jenkins machine.
It turned out that server was not completely up when the tests started executing.
Putting a sleep of few seconds in my bash script to allow Spring boot application to be up and running completely resolved the issue.
In my case i was making a request to a system that is using SSLV3.
So i have added the following jvm option. And problem got resolved.
-Dhttps.protocols="TLSv1,TLSv1.1,TLSv1.2"
For me, setting -Dhttps.protocols="TLSv1,TLSv1.1,TLSv1.2"
(or -Dhttps.protocols="TLSv1.2"
for that matter) didn't work.
Since I was running the problematic code in a Docker container in an AWS K8S cluster, I found a similar solution in the [AWS Documentation][1]
After setting this system property -Djdk.tls.client.protocols=TLSv1.2
, the error was gone.
[UPDATE]
After deploying this to production, I noticed the behaviour is intermittent: sometimes I emails were getting sent, sometimes they didn't.
Whilst researching some more, I found that my client was using TLS 1.0 which the server didn't support (it only supported TLS 1.2)
The verbose error messages I was getting is this:
javax.net.ssl|SEVERE|10|grpc-default-executor-0|2021-10-22 19:38:48.017 GMT|Logger.java:765|Fatal (HANDSHAKE_FAILURE): Couldn't kickstart handshaking
Finally, after multiple trials, I solved it using the answer from here: How to force JavaMailSenderImpl to use TLS1.2?
[1]: https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/security-java-tls.html
For my Spring Boot API consuming app, this issue was caused by being connected to a VPN.
I tried various work arounds including the accepted answer (I called System.setProperty("https.protocols", "TLSv1.1")
in my main function) but nothing worked.
I disconnected from the VPN and no longer got this error.
If using client certificates, it is also possible to trigger an error like this by having an expired, revoked or otherwise untrusted client certificate, particularly if it works for some clients and not for others and software is identical. For some reason Java does not bother checking its own end is somehow sane before complaining about the other end acting unexpectedly.
Almost any reason a TLS handshake could end unhappily in mid-exchange could be valid trigger for this kind of error.
Serverside (or general other-side) logs may you give more information about why the handshake was terminated.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.