SSLPeerUnverifiedException and debugging SSL connections

I’ve faced the problem of having to deal with a strange exception seen in our application log:

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

See full trace in a pastebin.

Looking about this you can find lots of things. Some are a bit mi leading and others give good grasp about what’s happening.

The context here is, we have an edge API that uses other internal API for random access data. We could see this problem for some of the requests (so it was not due a self-signed certificate or anything related). I’m attempting to share my experience of what has happening at the end.

Catching the exception

I started by catching the exception and trying to provide a bit more information about the requests that were producing the exception. I could not find any pattern about the type of requests.

Connection timeout?

One of our sysadmins pointed out that the problem could be generated by the socket timing out during the SSL handshake, as it’s pointed out in the following JIRA ticket: https://issues.apache.org/jira/browse/HTTPCLIENT-1070

While this could be the cause of the problem, we wanted to make sure that this was the case.

Analysing SSL errors

The “How to Analyse Java SSL Errors” post from dzone.com give me a good light about how to proceed. So I turned on the SSL debugging information by adding the following parameter when starting the server and try to find the problem:

-Djavax.net.debug=ssl:handshake

This is what I found:

qtp978883631-84, WRITE: TLSv1 Alert, length = 2
qtp978883631-91, WRITE: TLSv1 Handshake, length = 48
qtp978883631-84, called closeSocket()
qtp978883631-84, IOException in getSession():
    java.net.SocketTimeoutException: Read timed out
qtp978883631-84, called close()
qtp978883631-84, called closeInternal(true)

This is a great indicator that as our Systems guy was suggesting, connection is timing out during the SSL handshake.

At the end

The way I’ve tackled this issue is by silencing this kind of exceptions. We could have tried retrying the connection but we thought that the information provided by the second API is not as important and we will have the chance of trying again later in the following requests.