title: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate on Android 4.x and 5.x
body: <p>I am running my app on Android 4.4.2 and it throws this error:</p>
  
  <pre><code>07-03 08:43:59.255 21643-21803/com.myapp W/System.err: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
  07-03 08:43:59.255 21643-21803/com.myapp W/System.err:     at com.android.org.conscrypt.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:146)
  07-03 08:43:59.255 21643-21803/com.myapp W/System.err:     at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93)
  07-03 08:43:59.255 21643-21803/com.myapp W/System.err:     at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:388)
  07-03 08:43:59.255 21643-21803/com.myapp W/System.err:     at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)
  07-03 08:43:59.255 21643-21803/com.myapp W/System.err:     at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
  07-03 08:43:59.255 21643-21803/com.myapp W/System.err:     at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
  07-03 08:43:59.255 21643-21803/com.myapp W/System.err:     at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
  07-03 08:43:59.255 21643-21803/com.myapp W/System.err:     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
  07-03 08:43:59.255 21643-21803/com.myapp W/System.err:     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
  07-03 08:43:59.255 21643-21803/com.myapp W/System.err:     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
  07-03 08:43:59.255 21643-21803/com.myapp W/System.err:     at com.myapp.Util.Util$1.run(Util.java:242)
  07-03 08:43:59.255 21643-21803/com.myapp W/System.err:     at java.lang.Thread.run(Thread.java:841)
  07-03 08:43:59.475 21643-21643/com.myapp E/ViewRootImpl: sendUserActionEvent() mView == null
  </code></pre>
  
  <p>It works correctly on Android 6.x and above. Only Android 4.x and 5.x fail. I have not tried Android 3.x and below but I would be fine if I could only fix it for Android 4.x and 5.x. The interesting thing is that it used to work in the past and all of a sudden it stopped working without me changing the source code of the app. When I go to <a href="https://www.digicert.com/help/" rel="noreferrer">https://www.digicert.com/help/</a> to test my server SSL Certificate, everything passes:</p>
  
  <pre><code>DNS resolves &lt;Domain&gt; to &lt;IP address&gt;
  HTTP Server Header: Apache
  
  SSL certificate
  Common Name =
  
  Subject Alternative Names = &lt;subdomain&gt;.&lt;Domain&gt;, &lt;Domain&gt;, m.&lt;Domain&gt;, www.&lt;Domain&gt;
  
  Issuer = COMODO RSA Extended Validation Secure Server CA
  
  Serial Number = 5A34235B2A2B53B35354232B123B23C5
  
  SHA1 Thumbprint = 98C357AC34A23B232134B2A4C23A2B23AC23A532
  
  Key Length = 2048
  
  Signature algorithm = SHA256 + RSA (excellent)
  
  Secure Renegotiation: Supported
  
  SSL Certificate has not been revoked
  OCSP Staple:    Good
  OCSP Origin:    Good
  CRL Status: Good
  
  SSL Certificate expiration
  The certificate expires May 24, 2019 (325 days from today)
  
  Certificate Name matches &lt;Domain&gt;
  
  Subject 
  Valid from 11/Jun/2017 to 24/May/2019
  Issuer  COMODO RSA Extended Validation Secure Server CA
  
  
  Subject COMODO RSA Extended Validation Secure Server CA
  Valid from 12/Feb/2012 to 11/Feb/2027
  Issuer  COMODO RSA Certification Authority
  
  
  Subject COMODO RSA Certification Authority
  Valid from 30/May/2000 to 30/May/2020
  Issuer  AddTrust External CA Root
  SSL Certificate is correctly installed
  Congratulations! This certificate is correctly installed.
  </code></pre>
  
  <p>My SSL Certificate looks fine. I wonder why Android 4.x and 5.x are throwing this <code>javax.net.ssl.SSLPeerUnverifiedException: No peer certificate</code> error.</p>
  
  <p><strong>UPDATE 1</strong>: The SSL report shows that everything is fine with my SSL certificate. Why is Android complaining? This is the report:</p>
  
  <p><a href="https://i.stack.imgur.com/Y45rC.png" rel="noreferrer"><img src="https://i.stack.imgur.com/Y45rC.png" alt="enter image description here"></a></p>
  
  <p>I am using <a href="https://www.ssllabs.com/ssltest/" rel="noreferrer">https://www.ssllabs.com/ssltest/</a> </p>
  
  <p><strong>UPDATE 2</strong>: Reading <a href="https://developer.android.com/reference/javax/net/ssl/SSLPeerUnverifiedException.html#SSLPeerUnverifiedException(java.lang.String)" rel="noreferrer">https://developer.android.com/reference/javax/net/ssl/SSLPeerUnverifiedException.html#SSLPeerUnverifiedException(java.lang.String)</a>, what I understand is that the server was not able to identify itself. Why? I guess because in theory the server is missing the required peer certificate. It sounds like a contradiction if you see how when using <a href="https://www.ssllabs.com/ssltest/" rel="noreferrer">https://www.ssllabs.com/ssltest/</a> in UPDATE 1, the SSL Report shows that my server passes certificate tests correctly.</p>
  
  <p><strong>UPDATE 3</strong>: My certificate authority (CA) is COMODO. My SSL report shows that everything is good with my SSL certificate: <a href="https://www.ssllabs.com/ssltest/analyze.html?d=cuponclub.net" rel="noreferrer">https://www.ssllabs.com/ssltest/analyze.html?d=cuponclub.net</a>. When I make a server request from a web browser, everything is good: <a href="https://cuponclub.net/San-salvador/deals/json_index/" rel="noreferrer">https://cuponclub.net/San-salvador/deals/json_index/</a>. See how the HTTPS connection is successful, the certificate is valid from the browser and everything looks perfect. No errors on Android 6.x and above, but why is it that Android 4.x and 5.x keep complaining about my SSL certificate, throwing this error on the Android Studio logs when I try to compile my app on Android 4.x or 5.x?:</p>
  
  <pre><code>W/System.err: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
  W/System.err:     at com.android.org.conscrypt.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:146)
  W/System.err:     at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93)
  W/System.err:     at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:388)
  W/System.err:     at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)
  W/System.err:     at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
  W/System.err:     at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
  W/System.err:     at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
  W/System.err:     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
  W/System.err:     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
  W/System.err:     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
  W/System.err:     at com.couponclub.Util.Util$1.run(Util.java:242)
  W/System.err:     at java.lang.Thread.run(Thread.java:841)
  </code></pre>
  
  <p><strong>UPDATE 4</strong>: Looking at the answers at <a href="https://stackoverflow.com/questions/30232505/error-in-android-application-javax-net-ssl-sslpeerunverifiedexception-no-peer">Error in android application: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate</a>, they suggest that the problem could be related to the Server Name Indication (SNI). When I use <a href="https://www.ssllabs.com/ssltest/" rel="noreferrer">https://www.ssllabs.com/ssltest/</a> to analyze my site, I see this in the results in red:</p>
  
  <p>Alternative names   [................]  MISMATCH
  Trusted No   NOT TRUSTED 
  Mozilla  Apple  Android  Java  Windows </p>
  
  <p>Maybe my problem is related to this Server Name Indication (SNI) or the lack of it?</p>
  
  <p><strong>UPDATE 5</strong>: I am getting this "No SNI" in red from <a href="https://www.ssllabs.com/ssltest/" rel="noreferrer">https://www.ssllabs.com/ssltest/</a>. Maybe that is causing the problem?</p>
  
  <p><a href="https://i.stack.imgur.com/U5R3q.png" rel="noreferrer"><img src="https://i.stack.imgur.com/U5R3q.png" alt="enter image description here"></a></p>
  
  <p><strong>UPDATE 6</strong>: <code>Certificate #2</code> can be ignored for the effects of my question because it applies to a different domain. I only care about the results for <code>Certificate #1</code>.</p>
  
  <p><strong>UPDATE 7</strong>: The web hosting company support team and the SSL certificate issuer support team confirm that everything is fine with the SSL certificate and its installation, and they suggest this might be an issue about the Android SDK for Android 4.x and 5.x getting confused, and NOT an actual problem with the SSL certificate. Everything looks good with the SSL certificate.</p>
  
  <p><strong>UPDATE 8</strong>: I disabled TLS 1.1 and earlier on the server to comply with SSL standards and I am starting to suspect more that the cause of the bug is that Android 4.x and 5.x may expect to see libraries for support for TLS 1.1 and earlier and when it is not present, then it automatically throws an SSL error even though I do have TLS 1.2. That is one hypothesis that I have. For example, I was reading at <a href="https://help.salesforce.com/articleView?id=000231452&amp;type=1" rel="noreferrer">https://help.salesforce.com/articleView?id=000231452&amp;type=1</a> information about "Preparing mobile apps for TLS 1.0 deprecation" and they say this:</p>
  
  <blockquote>
    <p>Android. Unfortunately, some work might be required to ensure that
    your Android applications don’t break when TLS 1.0 is disabled on a
    Salesforce instance. We have a fix that enforces TLS 1.1 and 1.2 on
    Mobile SDK Android applications.</p>
  </blockquote>
  
  <p>So they were aware of the fact that disabling TLS 1.0 might make some Android apps to break for Salesforce instances, and they knew some work had to be done to fix that after disabling TLS 1.0. Similarly, I am starting to suspect that in my case, the problem could be the lack of support in my server for TLS 1.0 and earlier. </p>
  
  <p><strong>UPDATE 9</strong>: After I explained to COMODO CA support what I mentioned in <strong>UPDATE 8</strong>, this was their reply:</p>
  
  <blockquote>
    <p>Thank you for contacting Comodo CA support. Android versions 4.3 and
    earlier do not support TLS 1.2. As you have enabled only TLS 1.2 on
    the server, no connections will be established to your server from
    those legacy devices. Certificate check happens only after
    establishing the connection.</p>
  </blockquote>
  
  <p><strong>UPDATE 10</strong>: Everything seems to indicate that what is happening to me is what is explained at <a href="https://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/" rel="noreferrer">https://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/</a>:</p>
  
  <blockquote>
    <p>I recently had to work on an Android application that consumed an API which removed support for TLS 1.0 connections for security reasons. The Android documentation for SSLSocket says that TLS 1.1 and TLS 1.2 is supported within android starting API level 16+ (Android 4.1, Jelly Bean). But it is by default disabled but starting with API level 20+ (Android 4.4 for watch, Kitkat Watch and Android 5.0 for phone, Lollipop) they are enabled. But it is very hard to find any documentation about how to enable it for phones running 4.1 for example.</p>
  </blockquote>
  
  <p><strong>UPDATE 11</strong>: Looking at <a href="https://github.com/wireapp/wire-android/issues/1450" rel="noreferrer">https://github.com/wireapp/wire-android/issues/1450</a>, this is for example how <a href="http://wire.com" rel="noreferrer">wire.com</a>, a popular collaboration platform, justifies the lack of support for Android 4.x:</p>
  
  <blockquote>
    <p>Hi, thank you for your feedback. Unfortunately, upgrading to TLSv1.2
    was a necessary step to increase the security of the communications
    between our servers and the clients, and it is not really something we
    are open to reconsider. As with all decisions that involve dropping
    support for older versions of something, there will be people whose
    devices will be left behind. However, given the gains in terms of
    security and given the very small number of people that will lose
    support, we made the decision to upgrade. Know that we're not alone in
    dropping support for TLS pre-1.2, as Github itself has done the same.
    On top of all these reasons, Android 4.x phones are quite old devices
    that most likely are not receiving any security updates from their
    manufacturers, so if you are a "privacy-aware" user I would recommend
    getting something more recent (Android 5 came out in 2014). We're
    sorry if you felt like you were left behind, but please understand
    that this decision was taken with security in mind as the most
    important factor.</p>
  </blockquote>
  
  <p><strong>UPDATE 12</strong>: Interesting link about what the problem is and what to try to fix it: <a href="https://medium.com/tech-quizlet/working-with-tls-1-2-on-android-4-4-and-lower-f4f5205629a" rel="noreferrer">https://medium.com/tech-quizlet/working-with-tls-1-2-on-android-4-4-and-lower-f4f5205629a</a>. I already moved on as you can see in my answer to my own question, but maybe this link could be useful to somebody else.</p>