SSLHandshakeException: Handshake failed on Android N/7.0

Solution 1:

This is a known regression in Android 7.0, acknowledged by Google and fixed sometime before the release of Android 7.1.1. Here is the bug report: https://code.google.com/p/android/issues/detail?id=224438.

To be clear, the bug here is that 7.0 only supports ONE elliptic curve: prime256v1 aka secp256r1 aka NIST P-256, as Cornelis points out in the question. So if your users are facing this issue, these are the workarounds available to you (ignoring the fact that your users should ideally just upgrade to Android 7.1.1):

  • Configure your server to use the elliptic curve prime256v1. For example, in Nginx 1.10 you do this by setting ssl_ecdh_curve prime256v1;.

  • If that doesn't work, use older cipher suites that don't rely on elliptic-curve cryptography (e.g., DHE-RSA-AES256-GCM-SHA384) (make sure you understand what you're doing here in terms of data security)

NOTE: I am not an expert in elliptic-curve cryptography, make sure to do your own research on the security implications of my suggestions. Here are some other links I referred to while writing this answer:

  • https://community.letsencrypt.org/t/warning-android-7-0-clients-not-browsers-can-only-use-curve-prime256v1/23212
  • https://github.com/nodejs/node/issues/1495

Solution 2:

I had the problem with a Self Signed Certificate and the issue was in the cipher which wasn't accepted by Android 7.0

I ran: openssl s_client -showcerts -connect <domain>:<port>

in the result I found:

Protocol : TLSv1
Cipher   : DHE-RSA-AES256-SHA

I searched for the Android Equivalent of the Cipher and added it to my Retrofit Restadapter:

ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
            .tlsVersions(TlsVersion.TLS_1_2)
            .cipherSuites(

CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
            .build();

clientBuilder.connectionSpecs(Collections.singletonList(spec));

From here every connection with the correct certificate pinning or a correct certificate but with the 'wrong' cipher according to Android 7.0 was accepted.

When looking back at this answer a year later I have to admit I'm still happy I posted it, on the other hand, if you are in the position to change the certificate to the correct Cypher suite please do this always over "downgrading" te accepted suites in your app. If you have to work with a self-signed certificate (for example for embedded) this is a working solution for you.

Solution 3:

I have used this to fix "javax.net.ssl.SSLHandshakeException: Handshake failed" error and working fine for Android 7.0 and others version too.

put this in onCreate() method of application class.

fun initializeSSLContext(mContext: Context) {
            try {
                SSLContext.getInstance("TLSv1.2")
            } catch (e: NoSuchAlgorithmException) {
                e.printStackTrace()
            }

            try {
                ProviderInstaller.installIfNeeded(mContext.applicationContext)
            } catch (e: GooglePlayServicesRepairableException) {
                e.printStackTrace()
            } catch (e: GooglePlayServicesNotAvailableException) {
                e.printStackTrace()
            }

        }