testcontainers/testcontainers-java · warning

Retrying pull for image

Error message

Retrying pull for image: {} ({}s remaining)

What it means

RemoteDockerImage retries pulling an image for up to a time budget when the pull fails with InterruptedException or InternalServerErrorException (often Docker daemon timeouts or connection issues). This warning logs each retry attempt and how many seconds remain before retries stop.

Solutions

  1. Pre-pull the image with `docker pull <image>` before running tests
  2. Increase the retry budget via the testcontainers pull.timeout / retry settings (RemoteDockerImage withTimeLimit)
  3. Use a faster/closer registry mirror and check daemon/network stability

Example fix

// before
new RemoteDockerImage(DockerImageName.parse("postgres:16")).get();
// after: longer budget and pre-pull
new RemoteDockerImage(DockerImageName.parse("postgres:16"))
    .withTimeLimit(Duration.ofMinutes(10))
    .get();
Defensive patterns

Strategy: retry

Validate before calling

// pre-check image presence to avoid pulling
boolean present = new RemoteDockerImage(imageName).isPresent();
if (!present) { /* pre-pull with docker CLI or extend time budget */ }

Try / catch

try {
    String id = new RemoteDockerImage(imageName).get();
} catch (Exception e) {
    // retries already exhausted; check daemon health and registry connectivity
    throw new IllegalStateException("Image pull failed after retries: " + imageName, e);
}

Prevention

When it happens

Trigger: tryImagePullCommand catches InternalServerErrorException or InterruptedException from pullImage during RemoteDockerImage.resolve()/get(); repeated until the lastRetryAllowed deadline.

Common situations: Slow or flaky Docker Hub / registry connection; Docker daemon under heavy load returning 500s; corporate proxy throttling; large images timing out mid-pull.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/testcontainers/images/RemoteDockerImage.java:149

    }

    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 retried
                lastFailure.set(e);
                logger.warn(
                    "Retrying pull for image: {} ({}s remaining)",
                    imageName,
                    Duration.between(Instant.now(), lastRetryAllowed).getSeconds()
                );
                return false;
            }
        };
    }

    private TimeLimitedLoggedPullImageResultCallback pullImage(PullImageCmd pullImageCmd, Logger logger)
        throws InterruptedException {
        try {
            return pullImageCmd.exec(new TimeLimitedLoggedPullImageResultCallback(logger)).awaitCompletion();
        } catch (DockerClientException | NotFoundException e) {
            // Try to fallback to x86
            return pullImageCmd
                .withPlatform("linux/amd64")
                .exec(new TimeLimitedLoggedPullImageResultCallback(logger))

View on GitHub (pinned to 8e549514e3)