{"record":{"id":"1112201e1297a3e6","repo":"testcontainers/testcontainers-java","slug":"failed-to-pull-image-imagename","errorCode":null,"errorMessage":"Failed to pull image: ${imageName}","messagePattern":"Failed to pull image: (.+?)","errorType":"exception","errorClass":"ContainerFetchException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/testcontainers/images/RemoteDockerImage.java","lineNumber":122,"sourceCode":"            Awaitility\n                .await()\n                .pollInSameThread()\n                .pollDelay(Duration.ZERO) // start checking immediately\n                .atMost(PULL_RETRY_TIME_LIMIT)\n                .pollInterval(interval)\n                .until(\n                    tryImagePullCommand(pullImageCmd, logger, dockerImageName, imageName, lastFailure, lastRetryAllowed)\n                );\n\n            if (dockerImageName.get() == null) {\n                final Exception lastException = lastFailure.get();\n                logger.error(\n                    \"Failed to pull image: {}. Please check output of `docker pull {}`\",\n                    imageName,\n                    imageName,\n                    lastException\n                );\n                throw new ContainerFetchException(\"Failed to pull image: \" + imageName, lastException);\n            }\n\n            logger.info(\"Image {} pull took {}\", dockerImageName.get(), Duration.between(startedAt, Instant.now()));\n            LocalImagesCache.INSTANCE.refreshCache(imageName);\n            return dockerImageName.get();\n        } catch (DockerClientException e) {\n            throw new ContainerFetchException(\"Failed to get Docker client for \" + imageName, e);\n        }\n    }\n\n    private Callable<Boolean> tryImagePullCommand(\n        PullImageCmd pullImageCmd,\n        Logger logger,\n        AtomicReference<String> dockerImageName,\n        DockerImageName imageName,\n        AtomicReference<Exception> lastFailure,\n        Instant lastRetryAllowed\n    ) {","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/testcontainers/testcontainers-java/blob/8e549514e3f01c57d70546fbb8599d138f3903e5/core/src/main/java/org/testcontainers/images/RemoteDockerImage.java#L104-L140","documentation":"Testcontainers wraps any failure while pulling a Docker image into a ContainerFetchException with this message. The underlying cause is the last exception seen while streaming the docker pull (e.g. registry auth failures, image not found, network problems); the full docker pull output is logged at error level right before throwing.","triggerScenarios":"Calling RemoteDockerImage.resolve() (directly or via GenericContainer with an image that is not local) and the pullImageCmd/executable pull fails for all retry attempts — e.g. nonexistent tag, private registry without credentials, or no network/registry access.","commonSituations":"Typo in image name or tag (e.g. redis:latestr); pulling from Docker Hub rate limits (429 ToomanyRequests) without auth; corporate proxy blocking registry access; private registry missing docker-registry credentials in ~/.docker/config.json or Testcontainers config.","solutions":["Read the logged `docker pull <image>` output above the exception for the real cause (auth, not found, rate limit)","Verify the image name and tag exist: run `docker pull <imageName>` manually","Add registry credentials (DockerConfig or TestcontainersConfiguration with registry auth) for private registries","docker login to the registry and/or configure a registry mirror","Check network/proxy/VPN connectivity to the registry; retry if it was a transient failure"],"exampleFix":"// before\nnew GenericContainer(\"mycompany/private-app:latest\"); // ContainerFetchException\n// after\nnew GenericContainer(\"mycompany/private-app:1.4.2\") // correct existing tag\n  // plus credentials configured via docker login / TestcontainersConfiguration","handlingStrategy":"retry","validationCode":"// shell precheck before running the test\nboolean ok = new ProcessBuilder(\"docker\",\"pull\",imageName).inheritIO().start().waitFor() == 0;\nif (!ok) throw new IllegalStateException(\"Image not pullable: \" + imageName);","typeGuard":"null","tryCatchPattern":"try {\n    image.resolve(client);\n} catch (ContainerFetchException e) {\n    // inspect e.getCause(); check registry auth / rate limit before retrying\n    logger.error(\"Image pull failed for {}: {}\", imageName, e.getCause().getMessage());\n    throw e;\n}","preventionTips":["Always run `docker pull <image>` manually once before adding it to tests","Pin specific tags, never :latest, to avoid surprise removals","Authenticate to Docker Hub / private registries to avoid 429 rate limits","Configure registry mirrors for CI environments","Log the ContainerFetchException cause, not just the message"],"tags":["docker","image-pull","registry","network"],"backgroundTag":"http-error-response","analyzedSha":"8e549514e3f01c57d70546fbb8599d138f3903e5","analyzedAt":"2026-09-12T14:56:41.227Z","contentChangedAt":"2026-09-12T14:56:41.227Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}