• Android

Trust anchor for certification path not found

Also seen in: OkHttp, Retrofit, HttpsURLConnection, Volley, Flutter and React Native apps on Android, Android WebView

In one sentence

Android could not link the server's certificate to a root the app trusts: usually a missing intermediate, a private or proxy CA, or a root too new for the device.

Where you see it

In Android apps, in Logcat or in the app’s error reporting, whatever HTTP library the app uses: OkHttp, Retrofit, HttpsURLConnection, Volley, and the Android side of Flutter and React Native apps.

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

The text comes from Android’s TLS provider, Conscrypt (TrustManagerImpl.java), and the Android documentation shows it in Security with network protocols.

What it means

A trust anchor is a root certificate that the app trusts. To accept the server, Android must build a certificate chain from the server’s certificate, through any intermediates, to one of those roots. Here it could not. The Android documentation lists three common reasons: the CA that issued the server’s certificate is unknown, the certificate is self-signed, or the server does not send its intermediate.

By default, apps trust the CAs that came with the system. Apps that target Android 7.0 (API level 24) or higher do not trust CAs that users install, unless the app opts in (network security configuration). So a root that works in the phone’s browser may still fail inside an app.

Likely causes

The server does not send its intermediate certificate

Desktop browsers can fetch a missing intermediate or may have cached it from another site, so the site looks fine there. An Android app, in the words of the Android documentation, “isn’t as tolerant”. Confirm by counting the certificates the server sends:

openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null | grep -c 'BEGIN CERTIFICATE'

1 means only the server’s own certificate arrives. Fix it on the server: serve the certificate followed by its intermediate (How to build the full chain file your server needs). The Android documentation gives the same fix. No app change is needed.

The server uses a private CA or a self-signed certificate

Internal and test APIs often use a company CA or a self-signed certificate that is not among the system CAs. Fix: let the app trust that CA, for its own domains only, with a network security configuration. Put the CA certificate (PEM or DER) in res/raw/my_ca, and add res/xml/network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <trust-anchors>
            <certificates src="@raw/my_ca"/>
        </trust-anchors>
    </domain-config>
</network-security-config>

Point to it from the manifest with android:networkSecurityConfig="@xml/network_security_config" on the <application> element. For a self-signed server, prefer giving it a certificate from a private CA, so the app trusts the CA rather than one server certificate.

The device or user trusts a root, but the app does not

A company root or a debugging proxy’s root installed by the user is not trusted by most apps (see above). For debug builds only, a <debug-overrides> section with its own <trust-anchors> adds trusted CAs that apply only when the app is debuggable. For production, trust the company CA for its domains as shown above.

The device is too old to know the root

Old Android versions no longer receive root updates, so they miss newer roots. For example, Let's Encrypt's cross-signed chain for old Android devices expired (30 September 2024). Confirm which root the server’s chain ends at (the last i: line of openssl s_client -showcerts), and test on a current device. Fix: if you must support such devices, the app can trust the needed root for its own domains through the network security configuration, or the server can use a certificate from a CA those devices trust.

Check yours

Try it: Chain checkerOpen the full tool

Runs in your browser. Nothing you paste is sent anywhere.

Every certificate the server sends, leaf first. The output of openssl s_client -showcerts -connect example.com:443 works as it is: we ignore the text around the certificates.

Paste the certificates from openssl s_client -showcerts. The checker shows whether the intermediate is missing and which root the chain needs.

Learn why

In the gameLevel 12: Who do we trust?Registry of Roots, Keystone. In development

Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.

Last reviewed Edition 0.9