I can add some of my own observations to this below ... >> I haven't looked at the code, but my impression is that WANT_READ and WANT_WRITE are returned in two cases: when OpenSSL has received or sent a partial record and needs to complete it; or when the TLS state is such that OpenSSL needs to perform the associated operation and it hasn't been requested by the application - for example, if the application is trying to receive data but OpenSSL needs to send renegotiation information. >> >> If you do a non-blocking receive at a record boundary (so you don't have an incomplete record) and OpenSSL doesn't currently need to send for TLS reasons, OpenSSL will see the EAGAIN (or EWOULDBLOCK, depending on platform). I think in this case it does just return SSL_ERROR_SYSCALL, because OpenSSL itself doesn't "want" to receive. If OpenSSL had already received a partial record, then you'd get WANT_READ. > >I think the above guess is not correct. A cursory look at the >code suggests that even user-initiated reads normally return >SSL_ERROR_WANT_READ when the network bio signals a retriable >failure. > >The OP has not provided much detail about the connections in >question are created. Is the connection made by the >application, and SSL negotiated over an existing socket, or >is the connection established by OpenSSL over a "connect bio"? > >Is the handshake explicit, or does the application just call >SSL_read(), with OpenSSL performing the handshake as needed? > I occasionally (somewhat rarely) see the issue mentioned by the OP. Ignoring the error, or mapping it and do what WANT_READ/WANT_WRITE does effectively hides the issue and connection works fine. I predominantly run on Solaris 11. In my case, I open the socket myself, set non-blocking mode and associates with an SSL object using SS_set_fd(). The initial handshake is done explicitly.