testcontainers/testcontainers-java · warning

Unable to pre-fetch an image

Error message

Unable to pre-fetch an image ({}) depended upon by Docker Compose build - startup will continue but may fail. Exception message was: {}

What it means

ComposeDelegate.pullImages() pre-fetches images referenced by a locally built compose file so the build has them available. Each pre-fetch runs in parallel and any Exception from RemoteDockerImage.get() is swallowed with a WARN; startup continues but the later compose build may fail if the image is genuinely unavailable.

Solutions

  1. Pre-pull the base image manually (docker pull <imageName>) before the test runs
  2. Pin base image tags in the compose Dockerfile to tags that exist in the registry
  3. Configure Docker registry credentials for the private base image
  4. Verify network access to the registry from the test environment

Example fix

// before
FROM some-private-registry/base:latest
// after (pin an existing tag and pre-pull)
FROM some-private-registry/base:1.2.3  // ensure: docker pull some-private-registry/base:1.2.3
Defensive patterns

Strategy: fallback

Validate before calling

// Ensure the base image referenced by a compose build exists before the test
String base = "myregistry/base:1.2.3";
if (!imageExistsLocally(base)) {
    dockerClient.pullImageCmd(base).exec(new PullImageResultCallback()).awaitSuccess();
}

Prevention

When it happens

Trigger: A Docker Compose build references an image (from the 'image:' key of a service with 'build:') that cannot be pulled — registry unreachable, tag missing, or credentials absent.

Common situations: Building custom compose images whose base image tag was removed from Docker Hub; offline CI; private base images without auth.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/testcontainers/containers/ComposeDelegate.java:113

        this.defaultImageName = defaultImageName;
    }

    void pullImages() {
        // Pull images using our docker client rather than compose itself,
        // (a) as a workaround for https://github.com/docker/compose/issues/5854, which prevents authenticated image pulls being possible when credential helpers are in use
        // (b) so that credential helper-based auth still works when compose is running from within a container
        this.dockerComposeFiles.getDependencyImages()
            .forEach(imageName -> {
                try {
                    log.info(
                        "Preemptively checking local images for '{}', referenced via a compose file or transitive Dockerfile. If not available, it will be pulled.",
                        imageName
                    );
                    new RemoteDockerImage(DockerImageName.parse(imageName))
                        .withImageNameSubstitutor(ImageNameSubstitutor.noop())
                        .get();
                } catch (Exception e) {
                    log.warn(
                        "Unable to pre-fetch an image ({}) depended upon by Docker Compose build - startup will continue but may fail. Exception message was: {}",
                        imageName,
                        e.getMessage()
                    );
                }
            });
    }

    void createServices(
        boolean localCompose,
        boolean build,
        final Set<String> options,
        final List<String> services,
        final Map<String, Integer> scalingPreferences,
        Map<String, String> env,
        List<String> fileCopyInclusions
    ) {
        // services that have been explicitly requested to be started. If empty, all services should be started.

View on GitHub (pinned to 8e549514e3)