apache/hadoop · error · CertificateException

Unknown client chain certificate: {}

Error message

Unknown client chain certificate: {}

What it means

ReloadingX509TrustManager.checkClientTrusted throws CertificateException when its internal trustManagerRef is null, i.e. there is no loaded X509TrustManager to validate the client's certificate chain (chain[0] is echoed in the message). This is a server-side state failure: the reloadable trust manager could not supply trust material at handshake time, not a normal certificate rejection.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/ReloadingX509TrustManager.java:87

   * @throws GeneralSecurityException thrown if the truststore could not be
   * initialized due to a security error.
   */
  public ReloadingX509TrustManager(String type, String location, String password)
    throws IOException, GeneralSecurityException {
    this.type = type;
    this.password = password;
    trustManagerRef = new AtomicReference<X509TrustManager>();
    trustManagerRef.set(loadTrustManager(Paths.get(location)));
  }

  @Override
  public void checkClientTrusted(X509Certificate[] chain, String authType)
    throws CertificateException {
    X509TrustManager tm = trustManagerRef.get();
    if (tm != null) {
      tm.checkClientTrusted(chain, authType);
    } else {
      throw new CertificateException("Unknown client chain certificate: " +
                                     chain[0].toString());
    }
  }

  @Override
  public void checkServerTrusted(X509Certificate[] chain, String authType)
    throws CertificateException {
    X509TrustManager tm = trustManagerRef.get();
    if (tm != null) {
      tm.checkServerTrusted(chain, authType);
    } else {
      throw new CertificateException("Unknown server chain certificate: " +
                                     chain[0].toString());
    }
  }

  private static final X509Certificate[] EMPTY = new X509Certificate[0];
  @Override

View on GitHub (pinned to 2add963021)

Solutions

  1. Validate the truststore out of band: `keytool -list -keystore <truststore> -storetype <type>` with the configured password
  2. Fix ssl.<mode>.truststore.location / .type / .password in the SSL configuration so the initial load succeeds
  3. Check the service log for the companion 'Could not load truststore (keep using existing one)' message to find the underlying load failure
  4. Restart the service after repairing the truststore so a valid trust manager is installed

Example fix

# before: ssl-server.xml
ssl.server.truststore.type=jks   # file is actually PKCS12

# after
ssl.server.truststore.type=PKCS12
# verify with: keytool -list -keystore truststore.p12 -storetype PKCS12
Defensive patterns

Strategy: try-catch

Validate before calling

// startup check: truststore must load before the TLS listener is opened
KeyStore ks = KeyStore.getInstance(conf.get("ssl.server.truststore.type", "jks"));
try (InputStream in = Files.newInputStream(Paths.get(location))) {
  ks.load(in, password.toCharArray());
}
LOG.info("Truststore {} verified", location);

Try / catch

try {
  serverSocket.accept(); // handshake validation
} catch (SSLHandshakeException e) {
  if (e.getMessage().contains("Unknown client chain certificate")) {
    // trust material unavailable on our side: check truststore load logs, fix config, restart
    LOG.error("Trust manager not loaded; verify ssl.server.truststore.* settings", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: A server-side TLS handshake (HDFS DataNode/NameNode HTTPS, KMS, etc. using FileBasedKeyStoresFactory with a reloadable truststore) while the underlying trust manager failed to load or was left absent — for example truststore file missing/corrupt at startup in code paths that continue, or a failed reload in versions that null the reference.

Common situations: Truststore path typo so the file never loads; truststore replaced with a corrupt/truncated file during certificate rotation; type mismatch (PKCS12 file configured as jks).

Understand the failure class

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/12b5cc21be9837f9. Report an issue: GitHub.