testcontainers/testcontainers-java · error · ContainerFetchException
Failed to get Docker client for
Error message
Failed to get Docker client for ${imageName} What it means
RemoteDockerImage.resolve() catches DockerClientException raised by the Docker client (docker-java) after the pull attempt and rewraps it as ContainerFetchException 'Failed to get Docker client for <image>'. It indicates the Docker daemon/client interaction itself failed while resolving the image, not merely that the pull failed.
Solutions
- Verify Docker is running: `docker info` works from the same environment
- Check DOCKER_HOST / testcontainers docker.host config points to a valid daemon
- Restart the Docker daemon and rerun the test
- Check testcontainers/java-docker-client version compatibility; upgrade testcontainers
- Inspect the cause chain (DockerClientException) for the daemon-side error detail
Example fix
// before export DOCKER_HOST=tcp://localhost:2375 // daemon not listening -> DockerClientException // after eval $(minikube docker-env) // or unset DOCKER_HOST to use default unix socket
Defensive patterns
Strategy: try-catch
Validate before calling
// precheck that the daemon is reachable
boolean reachable = new ProcessBuilder("docker","info").inheritIO().start().waitFor() == 0;
if (!reachable) throw new IllegalStateException("Docker daemon not reachable; check DOCKER_HOST"); Type guard
null
Try / catch
try {
new RemoteDockerImage(imageName).resolve(dockerClient);
} catch (ContainerFetchException e) {
if (e.getCause() instanceof DockerClientException) {
throw new IllegalStateException("Docker client/daemon problem: " + e.getCause().getMessage(), e);
}
throw e;
} Prevention
- Verify `docker info` works in the same environment/CI job before tests
- Do not override DOCKER_HOST unless you mean to; validate its URL format
- Keep testcontainers and docker-java versions aligned
- Restart Docker Desktop/daemon when it has been suspended or updated
- Fail fast with an environment preflight check in CI
When it happens
Trigger: DockerClientException thrown inside resolve() — typically the docker-java client reports an error from the daemon (e.g. daemon unreachable after retries, invalid response from daemon) while resolving/pulling the image.
Common situations: Docker daemon not running or not reachable (DOCKER_HOST misconfigured); docker-java client version incompatibility; daemon restarting mid-test; malformed DOCKER_HOST/tls config.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- Can't close DockerClient
- You should never close the global DockerClient!
- Check failed:
- Requested port ( ) is not mapped
- execInContainer can only be used while the Container is…
AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12).
Data as JSON: /api/errors/2102e6d90c4b19a5.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/testcontainers/images/RemoteDockerImage.java:129
tryImagePullCommand(pullImageCmd, logger, dockerImageName, imageName, lastFailure, lastRetryAllowed)
);
if (dockerImageName.get() == null) {
final Exception lastException = lastFailure.get();
logger.error(
"Failed to pull image: {}. Please check output of `docker pull {}`",
imageName,
imageName,
lastException
);
throw new ContainerFetchException("Failed to pull image: " + imageName, lastException);
}
logger.info("Image {} pull took {}", dockerImageName.get(), Duration.between(startedAt, Instant.now()));
LocalImagesCache.INSTANCE.refreshCache(imageName);
return dockerImageName.get();
} catch (DockerClientException e) {
throw new ContainerFetchException("Failed to get Docker client for " + imageName, e);
}
}
private Callable<Boolean> tryImagePullCommand(
PullImageCmd pullImageCmd,
Logger logger,
AtomicReference<String> dockerImageName,
DockerImageName imageName,
AtomicReference<Exception> lastFailure,
Instant lastRetryAllowed
) {
return () -> {
try {
pullImage(pullImageCmd, logger);
dockerImageName.set(imageName.asCanonicalNameString());
return true;
} catch (InterruptedException | InternalServerErrorException e) {
// these classes of exception often relate to timeout/connection errors so should be retriedView on GitHub (pinned to 8e549514e3)