testcontainers/testcontainers-java · critical · IllegalStateException

Previous attempts to find a Docker environment failed. Will…

Error message

Previous attempts to find a Docker environment failed. Will not retry. Please see logs and check configuration

What it means

getFirstValidStrategy caches a hard failure in the FAIL_FAST_ALWAYS flag: once one strategy-selection pass has already failed, all later calls throw this IllegalStateException immediately instead of retrying. It signals that Testcontainers already concluded no usable Docker environment exists, so re-attempts are pointless until the JVM's configuration is fixed.

Solutions

  1. Ensure Docker is reachable before the JVM starts (docker ps must succeed) and restart the test JVM after fixing it
  2. Fix DOCKER_HOST / ~/.testcontainers.properties and rerun the tests — the flag is per-JVM, so a restart clears it
  3. Check earlier log lines for the concrete failure reasons recorded during the first strategy pass
  4. On Linux, add your user to the docker group or enable rootless Docker to fix permission-related first failures
Defensive patterns

Strategy: validation

Validate before calling

// Fail fast in setup if Docker is unavailable, before the JVM caches the failure
Process p = new ProcessBuilder("docker", "info").inheritIO().start();
if (p.waitFor(10, TimeUnit.SECONDS) && p.exitValue() != 0) {
    throw new IllegalStateException("Docker daemon unreachable; start Docker before running tests");
}

Try / catch

try {
    DockerClientFactory.instance().client();
} catch (IllegalStateException e) {
    if (e.getMessage().contains("Will not retry")) {
        // restart the JVM after fixing Docker; the flag is per-process
    }
    throw e;
}

Prevention

When it happens

Trigger: A second attempt to obtain a DockerClient (e.g. a second test class/container in the same JVM) after an earlier getFirstValidStrategy pass failed — Docker daemon down, DOCKER_HOST wrong, or socket permissions missing during the first pass.

Common situations: Docker Desktop not running; CI runner without Docker; user lacking group membership for /var/run/docker.sock; tests continuing after a first failed container startup.

Related errors


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

Appendix: source

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

                .atMost(TestcontainersConfiguration.getInstance().getClientPingTimeout(), TimeUnit.SECONDS) // timeout after configured duration
                .pollInterval(Duration.ofMillis(200)) // check state every 200ms
                .pollDelay(Duration.ofSeconds(0)) // start checking immediately
                .untilAsserted(() -> socket.connect(socketAddress));
            return true;
        } catch (Exception e) {
            log.warn("DOCKER_HOST {} is not listening", dockerHost, e);
            return false;
        }
    }

    /**
     * Determine the right DockerClientConfig to use for building clients by trial-and-error.
     *
     * @return a working DockerClientConfig, as determined by successful execution of a ping command
     */
    public static DockerClientProviderStrategy getFirstValidStrategy(List<DockerClientProviderStrategy> strategies) {
        if (FAIL_FAST_ALWAYS.get()) {
            throw new IllegalStateException(
                "Previous attempts to find a Docker environment failed. Will not retry. Please see logs and check configuration"
            );
        }

        List<String> configurationFailures = new ArrayList<>();
        List<DockerClientProviderStrategy> allStrategies = new ArrayList<>();

        // Manually enforce priority independent of priority property of strategy
        allStrategies.add(new TestcontainersHostPropertyClientProviderStrategy());
        allStrategies.add(new EnvironmentAndSystemPropertyClientProviderStrategy());

        // Next strategy to try out is the one configured using the Testcontainers configuration mechanism
        loadConfiguredStrategy().ifPresent(allStrategies::add);

        // Finally, add all other strategies ordered by their internal priority
        strategies
            .stream()
            .sorted(Comparator.comparing(DockerClientProviderStrategy::getPriority).reversed())

View on GitHub (pinned to 8e549514e3)