testcontainers/testcontainers-java · warning

CA cert under not found.

Error message

CA cert under  not found.

What it means

ElasticsearchContainer.caCertAsBytes copies the self-signed CA certificate (http_ca.crt) out of a v8-style Elasticsearch container. If the cert file is not present (NotFoundException from exec, e.g. because the image is actually v7 or a repackaged variant), it logs this warning and returns Optional.empty(). Callers like getClient/protocol then fall back to plain HTTP. The warning is intentional and non-fatal.

Solutions

  1. Pin an explicit version tag matching your intended major version (e.g. 7.17.9 or 8.11.0) instead of latest
  2. If using a v7 image, don't rely on the SSL client: use getHttpHostAddress and plain HTTP clients
  3. For custom images, ensure the CA cert exists at /usr/share/elasticsearch/config/certs/http_ca.crt or override withEnv security settings consistently
  4. Treat the Optional.empty() return: guard client code to handle absent CA (fallback to non-SSL)

Example fix

// before
ElasticsearchContainer es = new ElasticsearchContainer("elasticsearch:latest");
String caCertAsBase64 = Base64.getEncoder().encodeToString(es.caCertAsBytes()); // may NPE
// after
es.caCertAsBytes().ifPresentOrElse(
    cert -> connectWithSsl(cert),
    () -> connectPlainHttp(es.getHttpHostAddress())
);
Defensive patterns

Strategy: fallback

Validate before calling

// decide SSL vs plain from the Optional before building clients
Optional<byte[]> ca = container.caCertAsBytes();
boolean useSsl = ca.isPresent();

Try / catch

try {
    byte[] cert = container.caCertAsBytes().orElseThrow(() -> new IllegalStateException("No CA cert; image is not v8-style"));
    connectWithSsl(cert);
} catch (IllegalStateException e) {
    connectPlainHttp(container.getHttpHostAddress());
}

Prevention

When it happens

Trigger: The container image looks like Elasticsearch 8 (or uses the v8 default config path) so SSL setup is attempted, but /usr/share/elasticsearch/config/certs/http_ca.crt does not exist inside the container — typically a v7 image or a custom/repackaged image that resembles v8.

Common situations: Using elasticsearch:latest and getting a v7 image; custom Elasticsearch builds with plugins where the cert path differs; image tags like 8.0.0 but with security disabled in custom config so no cert is generated.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12). Data as JSON: /api/errors/f79712df07337c4e. Report an issue: GitHub.

Appendix: source

Thrown at modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/ElasticsearchContainer.java:151

    /**
     * If this is running above Elasticsearch 8, this will return the probably self-signed CA cert that has been extracted
     *
     * @return byte array optional containing the CA cert extracted from the docker container
     */
    public Optional<byte[]> caCertAsBytes() {
        if (StringUtils.isBlank(certPath)) {
            return Optional.empty();
        }
        try {
            byte[] bytes = copyFileFromContainer(certPath, IOUtils::toByteArray);
            if (bytes.length > 0) {
                return Optional.of(bytes);
            }
        } catch (NotFoundException e) {
            // just emit an error message, but do not throw an exception
            // this might be ok, if the docker image is accidentally looking like version 8 or latest
            // can happen if Elasticsearch is repackaged, i.e. with custom plugins
            log.warn("CA cert under " + certPath + " not found.");
        }
        return Optional.empty();
    }

    /**
     * A SSL context based on the self-signed CA, so that using this SSL Context allows to connect to the Elasticsearch service
     * @return a customized SSL Context
     */
    public SSLContext createSslContextFromCa() {
        try {
            CertificateFactory factory = CertificateFactory.getInstance("X.509");
            Certificate trustedCa = factory.generateCertificate(
                new ByteArrayInputStream(
                    caCertAsBytes()
                        .orElseThrow(() -> new IllegalStateException("CA cert under " + certPath + " not found."))
                )
            );
            KeyStore trustStore = KeyStore.getInstance("pkcs12");

View on GitHub (pinned to 8e549514e3)