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.

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.

Appendix: 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)