elastic/elasticsearch · error · RuntimeException

security exception

Error message

security exception

What it means

RuntimeException thrown from the cluster-health wait condition when WaitForHttpResource.wait raises a GeneralSecurityException. This typically means the HTTP wait attempted an SSL/TLS handshake (httpSslEnabled was true) and the TLS material or trust setup was invalid.

Source

Thrown at build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchCluster.java:667

                    getFirstNode().getHttpSocketURI(),
                    nodes.size()
                );
                if (httpSslEnabled) {
                    getFirstNode().configureHttpWait(wait);
                }
                List<Map<String, String>> credentials = getFirstNode().getCredentials();
                if (getFirstNode().getCredentials().isEmpty() == false) {
                    wait.setUsername(credentials.get(0).get("useradd"));
                    wait.setPassword(credentials.get(0).get("-p"));
                }
                return wait.wait(500);
            } catch (IOException e) {
                throw new UncheckedIOException("IO error while waiting cluster", e);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new TestClustersException("Interrupted while waiting for " + this, e);
            } catch (GeneralSecurityException e) {
                throw new RuntimeException("security exception", e);
            }
        });
    }

    @Nested
    public NamedDomainObjectContainer<ElasticsearchNode> getNodes() {
        return nodes;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ElasticsearchCluster that = (ElasticsearchCluster) o;
        return Objects.equals(clusterName, that.clusterName) && Objects.equals(path, that.path);
    }

    @Override

View on GitHub (pinned to db6a809a66)

Solutions

  1. Inspect the wrapped GeneralSecurityException cause (e.g. SSLHandshakeException, CertPathBuilderException) for the specific failure.
  2. Regenerate the test security fixtures (./gradlew :x-pack:plugin:core:internalClusterTest preparatory tasks or the security fixture tasks).
  3. Confirm SSL settings handed to configureHttpWait match the node's actual keystore/truststore configuration.
  4. On newer JDKs, check java.security for disabled algorithms (e.g. legacy TLS) affecting test certs.
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the node's keystore/truststore is readable before the wait
Path ks = node.getConfigDir().resolve("certs/http.p12");
if (!Files.exists(ks)) {
    throw new IllegalStateException("HTTP keystore missing; regenerate security fixtures");
}

Try / catch

try {
    cluster.start();
} catch (RuntimeException e) {
    if (e.getCause() instanceof GeneralSecurityException gse) {
        // regenerate test certs and rerun
        throw new IllegalStateException("TLS material invalid — run security fixture tasks", gse);
    }
    throw e;
}

Prevention

When it happens

Trigger: httpSslEnabled is true, getFirstNode().configureHttpWait(wait) installs TLS material, and wait.wait(500) performs an HTTPS request whose handshake fails with a cert/key/trust error. Original GeneralSecurityException is the cause.

Common situations: Mismatched or expired test certificates, wrong keystore password, missing CA trust, JDK security policy disabling an algorithm used by the test cert.

Related errors


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