testcontainers/testcontainers-java · warning

Exception while creating SSLSocketFactory

Error message

Exception while creating SSLSocketFactory

What it means

Testcontainers' strategy test (DockerClientProviderStrategy.test) failed to build an SSLSocketFactory from the SSLContext derived from the strategy's SSL config. This happens when the TLS material (keystore/truststore, certs, algorithms) in DOCKER_HOST TLS settings is unreadable or unusable. The strategy is then marked invalid and skipped, so Testcontainers falls through to other strategies and may ultimately report it could not find a Docker environment.

Solutions

  1. Regenerate the Docker client TLS certificates (openssl or `docker run --rm -v docker-certs:/certs alpine` style) so key.pem/cert.pem/ca.pem exist and are valid at DOCKER_CERT_PATH.
  2. If TLS is not required (local daemon on tcp://localhost:2375), unset DOCKER_CERT_PATH and use a plain tcp:// or unix:// DOCKER_HOST.
  3. Verify the key password matches what docker-java expects (DOCKER_TLS_VERIFY setup) and that the keystore algorithm is supported by your JVM (update JVM if NoSuchAlgorithmException on modern algorithms).
  4. Ensure file permissions allow the JVM user to read the cert/key files.

Example fix

// before
export DOCKER_HOST=tcp://docker.example.com:2376
export DOCKER_CERT_PATH=/stale/certs
// after
export DOCKER_CERT_PATH=~/.docker  # directory containing ca.pem, cert.pem, key.pem
# or drop TLS entirely for a local daemon:
export DOCKER_HOST=tcp://localhost:2375
Defensive patterns

Strategy: validation

Validate before calling

// Before starting containers, verify the TLS material is loadable
Path certPath = Paths.get(System.getenv().getOrDefault("DOCKER_CERT_PATH", ""));
if (System.getenv("DOCKER_HOST") != null && System.getenv("DOCKER_HOST").startsWith("https")) {
    if (!Files.isRegularFile(certPath.resolve("key.pem")) ||
        !Files.isRegularFile(certPath.resolve("cert.pem")) ||
        !Files.isRegularFile(certPath.resolve("ca.pem"))) {
        throw new IllegalStateException("DOCKER_CERT_PATH is missing key.pem/cert.pem/ca.pem: " + certPath);
    }
}

Try / catch

try {
    Container<?> c = new GenericContainer("alpine").withCreateContainerCmdModifier(cmd -> {});
    c.start();
} catch (IllegalStateException e) {
    if (e.getMessage() != null && e.getMessage().contains("Could not find a valid Docker environment")) {
        log.error("Docker TLS config invalid; check DOCKER_CERT_PATH", e);
    }
}

Prevention

When it happens

Trigger: DOCKER_HOST uses tcp/https scheme with an SSL config (transportConfig.getSslConfig() != null, e.g. DOCKER_CERT_PATH pointing at client certs) and initializing the SSLContext throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, or KeyStoreException.

Common situations: DOCKER_CERT_PATH points to missing, corrupt, or password-protected key.pem/cert.pem files; wrong keystore/truststore passwords; certs generated for a different JVM or using unsupported algorithms (e.g. PKCS12 vs JKS, modern algorithms on old JVMs); partial TLS setup where only some client cert files exist.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/testcontainers/dockerclient/DockerClientProviderStrategy.java:177

        Callable<Socket> socketProvider;
        SocketAddress socketAddress;
        switch (dockerHost.getScheme()) {
            case "tcp":
            case "http":
            case "https":
                SocketFactory socketFactory = SocketFactory.getDefault();
                SSLConfig sslConfig = transportConfig.getSslConfig();
                if (sslConfig != null) {
                    try {
                        socketFactory = sslConfig.getSSLContext().getSocketFactory();
                    } catch (
                        KeyManagementException
                        | UnrecoverableKeyException
                        | NoSuchAlgorithmException
                        | KeyStoreException e
                    ) {
                        log.warn("Exception while creating SSLSocketFactory", e);
                        return false;
                    }
                }
                socketProvider = socketFactory::createSocket;
                socketAddress = new InetSocketAddress(dockerHost.getHost(), dockerHost.getPort());
                break;
            case "unix":
            case "npipe":
                if (!new File(dockerHost.getPath()).exists()) {
                    log.debug("DOCKER_HOST socket file '{}' does not exist", dockerHost.getPath());
                    return false;
                }
                socketProvider =
                    () -> {
                        switch (dockerHost.getScheme()) {
                            case "unix":
                                return UnixSocket.get(dockerHost.getPath());
                            case "npipe":

View on GitHub (pinned to 8e549514e3)