elastic/elasticsearch · error · IllegalStateException

Trust-store does not contain any trusted certificate entries

Error message

Trust-store does not contain any trusted certificate entries

What it means

SslTrustResolver.checkForTrustEntry() iterates all aliases in the configured trustStore and throws if NONE of them is a certificate entry (`isCertificateEntry`). A trustStore with only key entries or empty aliases cannot establish any trust anchor, so TLS handshake would fail unconditionally — the resolver fails fast with a descriptive message instead.

Source

Thrown at build-tools/src/main/java/org/elasticsearch/gradle/testclusters/SslTrustResolver.java:138

        return sslContext;
    }

    private TrustManager[] getTrustManagers(KeyStore trustStore) throws GeneralSecurityException {
        checkForTrustEntry(trustStore);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustStore);
        return tmf.getTrustManagers();
    }

    private void checkForTrustEntry(KeyStore trustStore) throws KeyStoreException {
        Enumeration<String> enumeration = trustStore.aliases();
        while (enumeration.hasMoreElements()) {
            if (trustStore.isCertificateEntry(enumeration.nextElement())) {
                // found trusted cert entry
                return;
            }
        }
        throw new IllegalStateException("Trust-store does not contain any trusted certificate entries");
    }

    private static KeyStore buildTrustStoreFromCA(Set<File> files) throws GeneralSecurityException, IOException {
        final KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
        store.load(null, null);
        int counter = 0;
        for (File ca : files) {
            for (Certificate certificate : readCertificates(ca)) {
                store.setCertificateEntry("cert-" + counter, certificate);
                counter++;
            }
        }
        return store;
    }

    private static TrustManager[] buildTrustManagerFromLeafCertificates(Collection<? extends Certificate> certificates) {
        final Set<X509Certificate> trusted = certificates.stream()
            .filter(X509Certificate.class::isInstance)

View on GitHub (pinned to db6a809a66)

Solutions

  1. Verify the file is a trustStore: `keytool -list -v -keystore <file>` and confirm at least one entry shows `Entry type: trustedCertEntry`.
  2. If it's actually a keystore, re-export the public cert and import it into a fresh trustStore with `keytool -importcert -alias <a> -file <cert.pem> -keystore trust.jks`.
  3. Check the trustStore password matches what the resolver uses (a wrong password can yield zero readable entries).
  4. If you intended to trust a CA, switch to `.certificateAuthorities(...)` instead of a trustStore file.

Example fix

# before: passed a keystore as truststore
trustStoreFile = file('node-keystore.p12')
# after: import the cert into a real truststore
keytool -importcert -alias node -file node-cert.pem -keystore trust.jks -noprompt
# then
trustStoreFile = file('trust.jks')
Defensive patterns

Strategy: validation

Validate before calling

// Validate the trustStore has a cert entry before wiring it
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
try (InputStream in = Files.newInputStream(trustStore.toPath())) {
  ks.load(in, password.toCharArray());
}
boolean hasCert = Collections.list(ks.aliases()).stream().anyMatch(ks::isCertificateEntry);
if (!hasCert) throw new IllegalStateException("trustStore has no trustedCertEntry");

Prevention

When it happens

Trigger: Pointing `.trustStoreFile(...)` at a JKS/PKCS12 file that contains only private key entries (i.e. it's actually a keystore, not a truststore), or an empty/corrupt keystore file, or one whose cert entries were deleted.

Common situations: A developer mistakenly passes a node's keystore (containing the private key + its cert chain as key entries) as the client's trustStore; a generated test keystore where `keytool -genkey` was used instead of `-importcert`; a trustStore regenerated by tooling that strips entries; password mismatch causing aliases to enumerate as empty.

Understand the failure class

Related errors


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