grpc/grpc-java · error · CertificateException

Failed to find X509ExtendedTrustManager with default TrustMa

Error message

Failed to find X509ExtendedTrustManager with default TrustManager algorithm 

What it means

When the trust manager is configured to use system default trust certificates, it iterates the default TrustManagerFactory's managers looking for an X509ExtendedTrustManager. If none of the returned managers is an X509ExtendedTrustManager instance, it throws this CertificateException because hostname/peer verification depends on the extended interface. This indicates the JVM's default TrustManager algorithm produced only basic X509TrustManagers.

Source

Thrown at util/src/main/java/io/grpc/util/AdvancedTlsX509TrustManager.java:146

  }

  private static X509ExtendedTrustManager createDelegateTrustManager(KeyStore keyStore)
      throws CertificateException, KeyStoreException, NoSuchAlgorithmException {
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(
        TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(keyStore);
    X509ExtendedTrustManager delegateManager = null;
    TrustManager[] tms = tmf.getTrustManagers();
    // Iterate over the returned trust managers, looking for an instance of X509TrustManager.
    // If found, use that as the delegate trust manager.
    for (TrustManager tm : tms) {
      if (tm instanceof X509ExtendedTrustManager) {
        delegateManager = (X509ExtendedTrustManager) tm;
        break;
      }
    }
    if (delegateManager == null) {
      throw new CertificateException(
          "Failed to find X509ExtendedTrustManager with default TrustManager algorithm "
              + TrustManagerFactory.getDefaultAlgorithm());
    }
    return delegateManager;
  }

  private void checkTrusted(X509Certificate[] chain, String authType, SSLEngine sslEngine,
      Socket socket, boolean checkingServer) throws CertificateException {
    if (chain == null || chain.length == 0) {
      throw new IllegalArgumentException(
          "Want certificate verification but got null or empty certificates");
    }
    if (sslEngine == null && socket == null) {
      throw new CertificateException(NOT_ENOUGH_INFO_MESSAGE);
    }
    if (this.verification != Verification.INSECURELY_SKIP_ALL_VERIFICATION) {
      X509ExtendedTrustManager currentDelegateManager = this.delegateManager;
      if (currentDelegateManager == null) {

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Inspect java.security's ssl.TrustManagerFactory.algorithm and security.provider list; restore the default JSSE provider (SunJSSE) so PKIX yields X509ExtendedTrustManager.
  2. Run on a standard JVM (JDK 7+ SunJSSE always returns X509ExtendedTrustManager) instead of a stripped/embedded JRE.
  3. Avoid useSystemDefaultTrustCerts; call updateTrustCredentials(CertificateType.FILE_PATH, ...) with an explicit CA bundle and skip delegate creation from the default factory.
  4. Verify no library on the classpath replaces the default TrustManagerFactory via Security.setProperty before this call.

Example fix

// before
trustManager.useSystemDefaultTrustCerts();

// after
trustManager.updateTrustCredentials(
    CertificateType.FILE_PATH,
    "/etc/ssl/certs/ca-certificates.crt",
    /*certChainCheckingIntervalMs*/ 60000);
Defensive patterns

Strategy: validation

Validate before calling

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null);
boolean hasExtended = false;
for (TrustManager tm : tmf.getTrustManagers()) {
  if (tm instanceof X509ExtendedTrustManager) { hasExtended = true; break; }
}
if (!hasExtended) {
  throw new IllegalStateException("Default algorithm yields no X509ExtendedTrustManager; configure CA file instead");
}

Type guard

static boolean isExtended(TrustManager tm) {
  return tm instanceof X509ExtendedTrustManager;
}

Try / catch

try {
  trustManager.useSystemDefaultTrustCerts();
} catch (CertificateException e) {
  if (e.getMessage().startsWith("Failed to find X509ExtendedTrustManager")) {
    trustManager.updateTrustCredentials(CertificateType.FILE_PATH, caBundlePath, 60000);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling useSystemDefaultTrustCerts() or updateTrustCredentials(systemDefault) when TrustManagerFactory.getDefaultAlgorithm() (typically 'PKIX') returns managers that do not include an X509ExtendedTrustManager.

Common situations: Custom security providers (java.security security.provider overrides) that supply non-extended trust managers; exotic or embedded JVMs with a reduced JSSE; a Security property override of ssl.TrustManagerFactory.algorithm pointing to a non-JSSE provider; classloader/pro shading issues where X509ExtendedTrustManager resolution fails.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/98883db334ffd6b4. Report an issue: GitHub.