If you’re using Retrofit or OkHttp in your Android app and encounter this dreaded error:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found
you’re not alone.
This often happens when your Android app connects to an HTTPS server using a Let’s Encrypt certificate — and the device (especially those on Android 7 or 8) does not recognize the new ISRG Root X1 as a valid Certificate Authority.
In this guide, we’ll walk through:
- Why this error occurs
- How to fix it with a custom
TrustManager - Code examples using Retrofit and OkHttp
- Security considerations
🤔 Why Does This Error Happen?
Let’s Encrypt used to rely on DST Root CA X3, but this expired on Sept 30, 2021. Modern systems trust the new ISRG Root X1, but many Android 7–9 devices do not have this root installed.
So, when OkHttp/Retrofit tries to establish an HTTPS connection, Android can’t validate the server’s certificate → handshake fails → SSLHandshakeException.
✅ The Fix: Use a Custom TrustManager with Retrofit
We’ll load the correct certificate into a custom trust store and attach it to an OkHttpClient used by Retrofit.
🔧 Step-by-Step Guide
1. Download the ISRG Root X1 Certificate
Get the certificate from Let’s Encrypt:
Rename it to isrg_root_x1.pem, and place it in res/raw/ in your Android project.
2. Create the Custom TrustManager
public class SslHelper {
public static SSLSocketFactory getSocketFactory(Context context) throws Exception {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(context.getResources().openRawResource(R.raw.isrg_root_x1));
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
// Create a KeyStore with our trusted cert
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager with that KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses the TrustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
return sslContext.getSocketFactory();
}
public static X509TrustManager getTrustManager(Context context) throws Exception {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(context.getResources().openRawResource(R.raw.isrg_root_x1));
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
return (X509TrustManager) tmf.getTrustManagers()[0];
}
}
3. Configure OkHttpClient and Retrofit
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
try {
SSLSocketFactory sslSocketFactory = SslHelper.getSocketFactory(context);
X509TrustManager trustManager = SslHelper.getTrustManager(context);
httpClientBuilder.sslSocketFactory(sslSocketFactory, trustManager);
} catch (Exception e) {
e.printStackTrace(); // Handle or log error
}
OkHttpClient okHttpClient = httpClientBuilder.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://your.server.com/")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
4. Use Retrofit Normally
public interface MyApiService {
@HEAD
Call<Void> checkUpdate(@Url String url);
}
⚠️ Security Considerations
- ✅ Only trust the specific certificate(s) you add — don’t disable verification globally.
- ❌ Do not bypass SSL with
HostnameVerifieror “trust all certificates” approaches in production. - ✅ Always use HTTPS — never downgrade to HTTP for compatibility.
🧪 Bonus: Test with OpenSSL or cURL
To check if your server is serving the correct certificate chain:
openssl s_client -connect your.server.com:443 -showcerts
Or:
curl -Iv https://your.server.com
✅ Conclusion
To fix javax.net.ssl.SSLHandshakeException: Trust anchor for certification path not found in Android when using Retrofit and Let’s Encrypt:
- Use a custom
TrustManagerwith ISRG Root X1. - Configure your
OkHttpClientto use the updated trust chain. - Avoid “trust-all” insecure workarounds in production.
With this setup, your app will work seamlessly on Android 7, 8, and newer versions — without sacrificing security.


