When trying to establish a TLS connection, the above message was seen intermittently. Other messages included “The underlying connection was closed: The connection was closed unexpectedly.”
At the same time these apparent comms errors occurred, looking in the System event log showed a lot of Schannel EventCode 36888 with the message:
"The following fatal alert was generated: 80. The internal error state is 301."
The explanation for code 80 from http://blogs.msdn.com/b/kaushal/archive/2012/10/06/ssl-tls-alert-protocol-amp-the-alert-codes.aspx is:
An internal error unrelated to the peer or the correctness of the protocol makes it impossible to continue, such as a memory allocation failure. The error is not related to protocol. This message is always fatal.
The key to solving this was memory allocation failure, it was not the external system but internal memory pressure that was causing the problem. Fixing the memory issue also resolved the communications issues.
Unfortunately this is just one cause of this error message, other times it has turned out to be the external system in which case System.Net tracing could help:
(At the time, one of the external systems had upgraded a version of Apache that had an issue in mod_proxy_http).
Currently trying to diagnose some .NET connection failures so I ported my code to Java to see if I could eliminate some causes as this won’t use SChannel (instead using JSSE).
To do this I chose the Apache HttpClient (version 4.3) – running multiple calls it seemed to be working but quite slowly. Wireshark revealed that it was doing a handshake every time. See multiple client hellos:
TCPView also showed multiple connections being established:
Despite trying BasicHttpClientConnectionManager and PoolingHttpClientConnectionManager with a pool size of 1 it still wouldn’t reuse the connection. Keep-Alive headers were being sent by the server but as shown in the SSL diagnostics (using -Djavax.net.debug=all), the socket was still closed:
Keep-Alive: timeout=10, max=100, Connection: Keep-Alive]}
main, called close()
main, called closeInternal(true)
main, SEND TLSv1.1 ALERT: warning, description = close_notify
In my scenario, I expected the response from the server to only contain a location header and no body however I then noticed was the content-length was set to 20.
So the problem was that I was not fully consuming/reading the body of the response, doing so meant the socket could be re-used:
HttpEntity entity = response.getEntity();
// do something useful with the response body
// and ensure it is fully consumed otherwise connection is not reused
Now I get a much nicer looking wireshark trace!
Of course now I know the answer – I can also find it on stackoverflow: http://stackoverflow.com/questions/8200038/httpclient-4-x-connection-reuse-not-happening