grpc/grpc-java · error · CertStoreException
Native X509 TrustManager not found.
Error message
Native X509 TrustManager not found.
What it means
Inside XdsTrustManagerFactory's custom TrustManager engine, createTrustManager picks a default X509ExtendedTrustManager from the JVM's default trust manager list and casts it for delegation. If no element of the returned default trust managers is an X509ExtendedTrustManager, it throws CertStoreException('Native X509 TrustManager not found.'), meaning the runtime environment lacks the expected native trust manager implementation.
Source
Thrown at xds/src/main/java/io/grpc/xds/internal/security/trust/XdsTrustManagerFactory.java:182
i++;
}
tmf.init(ks);
} catch (NoSuchAlgorithmException | KeyStoreException | IOException | CertificateException e) {
logger.log(Level.SEVERE, "createX509TrustManager", e);
throw new CertStoreException(e);
}
TrustManager[] tms = tmf.getTrustManagers();
X509ExtendedTrustManager myDelegate = null;
if (tms != null) {
for (TrustManager tm : tms) {
if (tm instanceof X509ExtendedTrustManager) {
myDelegate = (X509ExtendedTrustManager) tm;
break;
}
}
}
if (myDelegate == null) {
throw new CertStoreException("Native X509 TrustManager not found.");
}
return myDelegate;
}
@Override
protected void engineInit(KeyStore keyStore) throws Exception {
throw new UnsupportedOperationException();
}
@Override
protected void engineInit(ManagerFactoryParameters managerFactoryParameters) throws Exception {
throw new UnsupportedOperationException();
}
@Override
protected TrustManager[] engineGetTrustManagers() {
return new TrustManager[] {xdsX509TrustManager};
}View on GitHub (pinned to 64daddc1f3)
Solutions
- Check TrustManagerFactory.getDefaultAlgorithm() and the installed security providers; remove/reorder providers that shadow the standard X509ExtendedTrustManager
- Run on a standard JDK/JRE that exposes X509ExtendedTrustManager from the default trust manager factory
- Explicitly configure the algorithm (ssl.TrustManagerFactory.algorithm=PKIX / SunX509) in java.security so the default TM is the extended one
- Provide your own trust manager wiring instead of relying on the default if the environment cannot be changed
Example fix
// before: security.provider.1=com.example.CustomProvider (returns plain X509TrustManager) // after: keep default providers first, custom ones later security.provider.1=sun.security.provider.Sun security.provider.2=com.example.CustomProvider
Defensive patterns
Strategy: try-catch
Validate before calling
// Detect the problem early at startup
for (TrustManager tm : TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).getTrustManagers()) {
if (tm instanceof X509ExtendedTrustManager) return; // ok
}
throw new IllegalStateException("No X509ExtendedTrustManager in default trust managers; xDS TLS will fail"); Type guard
static boolean hasExtendedTrustManager(TrustManager[] tms) {
for (TrustManager tm : tms) if (tm instanceof X509ExtendedTrustManager) return true;
return false;
} Try / catch
try {
engineInit();
} catch (CertStoreException e) {
if ("Native X509 TrustManager not found.".equals(e.getMessage())) {
logger.error("Default trust managers lack X509ExtendedTrustManager; check security providers/JVM", e);
}
throw e;
} Prevention
- Run on a standard JDK exposing X509ExtendedTrustManager via the default algorithm
- Avoid security providers that shadow the default TrustManagerFactory implementation
- Smoke-test TLS handshake at boot in constrained JVMs/embedded runtimes
When it happens
Trigger: engineInit initializing with default JVM trust store when TrustManagerFactory.getDefaultAlgorithm() returns a factory whose getTrustManagers() contains no X509ExtendedTrustManager instance — e.g. unusual JCE provider ordering, custom security providers, or non-standard JDKs/Android runtimes.
Common situations: Running on a JRE with a custom TrustManagerFactory provider replacing the default; minimal/embedded JVMs without the standard SunJSSE extended trust manager; classpath security provider overrides.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Failed to find X509ExtendedTrustManager with default TrustMa
- Not supported: ${specifierCase}
- Not enough information to validate peer. SSLEngine or Socket
- TlsCredentials input stream construction pending.
- common-tls-context is required in upstream-tls-context
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/59bd208b9a45fa48.
Report an issue: GitHub.