okhttp: SSLHandshakeException on Android 5 (API 21)

I pushed a new version of my app to production and started to get bunch of complains from users. Turns out with okhttp 4.3.0 there is SSLHandshakeException happening only on Android 5 for some reason. I’m getting this exception for all my requests including requests from 3th party SDKs. It’s reproducible on API 21 Emulator.

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:306)
        at com.android.okhttp.Connection.upgradeToTls(Connection.java:197)
        at com.android.okhttp.Connection.connect(Connection.java:151)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:276)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:211)
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:373)
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:323)
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:491)
        at com.android.okhttp.internal.http.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
        at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:25)
...
     Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:318)
        at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:219)
        at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:113)
        at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:525)
        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
        at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:302)
        at com.android.okhttp.Connection.upgradeToTls(Connection.java:197) 
        at com.android.okhttp.Connection.connect(Connection.java:151) 
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:276) 
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:211) 
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:373) 
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:323) 
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:491) 
        at com.android.okhttp.internal.http.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105) 
        at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:25) 
...
     Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:318) 
        at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:219) 
        at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:113) 
        at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:525) 
        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method) 
        at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:302) 
        at com.android.okhttp.Connection.upgradeToTls(Connection.java:197) 
        at com.android.okhttp.Connection.connect(Connection.java:151) 
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:276) 
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:211) 
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:373) 
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:323) 
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:491) 
        at com.android.okhttp.internal.http.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105) 
        at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:25) 
...

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 23

Most upvoted comments

@swankjesse heads up another fix for 4.3.1

We lost this code in 4.3, which breaks some hosts on Android 5

      // This is SSLParameters.setServerNames() in API 24+.
      setHostname.invoke(sslSocket, hostname)

@vipulasri this certificate chain isn’t supported on Android 21, there is no root CA certificate in the Android TrustManager.

See https://talkatone.zendesk.com/hc/en-us/articles/360044415672-Android-Users-Running-OS-Versions-4-4-4-5-0- https://serverfault.com/questions/792143/why-is-my-ssl-certificate-untrusted-on-android

Please continue any further discussion in a forum like stackoverflow, I’ve mainly been using this as a was to look at reproducing similar issues. But it’s not a bug and not something we actively support.

@yschimke thank you so much for sharing your insights. Seems like something not related to okhttp.

@yschimke Can you please try this endpoint: https://www.wikiart.org/ for reproducing the behavior?