testcontainers/testcontainers-java · warning

Couldn't set DOCKER_CERT_PATH. `sslConfig` is present but…

Error message

Couldn't set DOCKER_CERT_PATH. `sslConfig` is present but it's not LocalDirectorySSLConfig.

What it means

Testcontainers logs this warning when a DockerClientConfig has an `sslConfig` set, but it is not a LocalDirectorySSLConfig. Only LocalDirectorySSLConfig (a directory on disk containing ca.pem/cert.pem/key.pem) can be translated into the DOCKER_CERT_PATH/DOCKER_TLS_VERIFY environment variables that docker-compose needs to reach a TLS-secured Docker daemon. Other SSLConfig implementations are silently ignored, so the compose container may fail to authenticate to the daemon.

Solutions

  1. Configure the Docker client with new LocalDirectorySSLConfig("/path/to/cert/dir") so DOCKER_CERT_PATH and DOCKER_TLS_VERIFY can be set.
  2. Ensure the cert directory contains ca.pem, cert.pem and key.pem and is readable by the test process.
  3. If a custom SSLConfig is required, write the certs to disk first and wrap that directory in LocalDirectorySSLConfig, or drop TLS by using a local daemon/socket.

Example fix

// before
DefaultDockerClientConfig.builder()
    .withDockerTlsVerify(true)
    .withCustomSslConfig(myCustomSslConfig) // not LocalDirectorySSLConfig
    .build();
// after
DefaultDockerClientConfig.createDefaultConfigBuilder()
    .withDockerHost("tcp://remote:2376")
    .withDockerTlsVerify(true)
    .withDockerCertPath("/home/user/.docker/certs") // becomes LocalDirectorySSLConfig
    .build();
Defensive patterns

Strategy: validation

Validate before calling

if (config.getSSLConfig() != null && !(config.getSSLConfig() instanceof LocalDirectorySSLConfig)) {
    throw new IllegalArgumentException("sslConfig must be LocalDirectorySSLConfig for DockerComposeContainer");
}

Type guard

if (sslConfig instanceof LocalDirectorySSLConfig) { String path = ((LocalDirectorySSLConfig) sslConfig).getDockerCertPath(); }

Prevention

When it happens

Trigger: Calling LocalDockerCompose.invoke() (via DockerComposeContainer) while the underlying DockerClientConfig's sslConfig is non-null and of a type other than LocalDirectorySSLConfig (e.g. a custom SSLConfig implementation).

Common situations: Running against a remote TLS-enabled Docker daemon (e.g. tcp://host:2376) where the client was configured with a non-directory-based SSL config, or a custom SSLConfig subclass; the compose invocation then cannot pass the client certificates.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/testcontainers/containers/LocalDockerCompose.java:77

        // bail out early
        if (!CommandLine.executableExists(this.composeExecutable)) {
            throw new ContainerLaunchException(
                "Local Docker Compose not found. Is " + this.composeExecutable + " on the PATH?"
            );
        }

        final Map<String, String> environment = Maps.newHashMap(env);
        environment.put(ENV_PROJECT_NAME, identifier);

        TransportConfig transportConfig = DockerClientFactory.instance().getTransportConfig();
        SSLConfig sslConfig = transportConfig.getSslConfig();
        if (sslConfig != null) {
            if (sslConfig instanceof LocalDirectorySSLConfig) {
                environment.put("DOCKER_CERT_PATH", ((LocalDirectorySSLConfig) sslConfig).getDockerCertPath());
                environment.put("DOCKER_TLS_VERIFY", "true");
            } else {
                logger()
                    .warn(
                        "Couldn't set DOCKER_CERT_PATH. `sslConfig` is present but it's not LocalDirectorySSLConfig."
                    );
            }
        }
        String dockerHost = transportConfig.getDockerHost().toString();
        environment.put("DOCKER_HOST", dockerHost);

        final Stream<String> absoluteDockerComposeFilePaths = composeFiles
            .stream()
            .map(File::getAbsolutePath)
            .map(Objects::toString);

        final String composeFileEnvVariableValue = absoluteDockerComposeFilePaths.collect(
            Collectors.joining(File.pathSeparator + "")
        );
        logger().debug("Set env COMPOSE_FILE={}", composeFileEnvVariableValue);

        final File pwd = composeFiles.get(0).getAbsoluteFile().getParentFile().getAbsoluteFile();

View on GitHub (pinned to 8e549514e3)