Fighting with the SSL “unexpected_message” while using HTTP proxy and your own socket tunnel

Whenever you write an application that should support http proxies with your own custom SSLSocketFactory, you MIGHT run into a problem…

Java JRE in itself supports proxies for HTTPS but it does NOT support SSL connections over proxy. For that you’ll need to create a separate proxy tunneling socket and layer it on top of the actual SSL connection. So far so good but there’s a nasty exception that can take you ages to figure out:

Caused by: javax.net.ssl.SSLException: Received fatal alert: unexpected_message
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1682)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:932)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1112)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1139)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123)

There can be many reasons but one of the unexpected ones — make sure to add

Pragma: no-cache

to your http proxy CONNECT request header! Otherwise you’ll get this exception.