elastic/elasticsearch · error · SslConfigException

Cannot combine trust configurations

Error message

Cannot combine trust configurations [{}]

What it means

Thrown as SslConfigException by CompositeTrustConfig.createTrustManager when merging trust anchors from multiple SslTrustConfig entries fails with a GeneralSecurityException. CompositeTrustConfig collects all accepted issuers from each child config, builds a combined KeyStore, and initializes a TrustManagerFactory; any certificate-encoding, keystore-loading, or factory-init failure bubbles up wrapped in this message, which lists the string representation of all configs for diagnosis.

Solutions

  1. Inspect the exception's cause (GeneralSecurityException) for the specific certificate or algorithm error.
  2. Validate each PEM/DER/PKCS12 certificate file independently with keytool -printcert or openssl x509 -in <file> -text -noout.
  3. Remove or replace the offending certificate from the trust configuration.
  4. If combining many CAs, test them one at a time to isolate the problematic entry.

Example fix

// before — combine multiple trust configs, one has a corrupt cert
CompositeTrustConfig composite = new CompositeTrustConfig(List.of(pemConfig, p12Config));
composite.createTrustManager();

// after — validate each cert first, drop the bad one
// run: openssl x509 -in ca.pem -text -noout  (fix or remove failing cert)
CompositeTrustConfig composite = new CompositeTrustConfig(List.of(validPemConfig, p12Config));
composite.createTrustManager();
Defensive patterns

Strategy: try-catch

Try / catch

try {
    X509ExtendedTrustManager tm = compositeTrustConfig.createTrustManager();
} catch (SslConfigException e) {
    // e.getCause() is the GeneralSecurityException with the real reason
    log.error("Failed to build composite trust manager: {}", e.getMessage(), e.getCause());
    // isolate which child config fails by calling each createTrustManager() individually
}

Prevention

When it happens

Trigger: Calling createTrustManager() on a CompositeTrustConfig whose child configs include a corrupt, expired, or unsupported certificate, or whose combined certificate set causes TrustManagerFactory.init() to fail.

Common situations: An SSL/TLS configuration combines CA certificates from multiple sources (e.g. a PEM certificate authority file plus a JDK default trust store plus a PKCS#12 file). One certificate is malformed, uses an unsupported algorithm, or has an encoding the default TrustManagerFactory rejects. Common in x-pack security transport or HTTP TLS setup with mixed trust sources.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/512cd200d4e84a37. Report an issue: GitHub.

Appendix: source

Thrown at libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/CompositeTrustConfig.java:61

    }

    @Override
    public boolean hasExplicitConfig() {
        return configs.stream().allMatch(SslTrustConfig::hasExplicitConfig);
    }

    @Override
    public X509ExtendedTrustManager createTrustManager() {
        try {
            Collection<Certificate> trustedIssuers = configs.stream()
                .map(c -> c.createTrustManager())
                .map(tm -> tm.getAcceptedIssuers())
                .flatMap(Arrays::stream)
                .collect(Collectors.toSet());
            final KeyStore store = KeyStoreUtil.buildTrustStore(trustedIssuers);
            return KeyStoreUtil.createTrustManager(store, TrustManagerFactory.getDefaultAlgorithm());
        } catch (GeneralSecurityException e) {
            throw new SslConfigException(
                "Cannot combine trust configurations ["
                    + configs.stream().map(SslTrustConfig::toString).collect(Collectors.joining(","))
                    + "]",
                e
            );
        }
    }

    @Override
    public Collection<? extends StoredCertificate> getConfiguredCertificates() {
        return configs.stream().map(SslTrustConfig::getConfiguredCertificates).flatMap(Collection::stream).toList();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CompositeTrustConfig that = (CompositeTrustConfig) o;

View on GitHub (pinned to db6a809a66)