{"record":{"id":"1c5c970b6792011b","repo":"testcontainers/testcontainers-java","slug":"unable-to-delete-image","errorCode":null,"errorMessage":"Unable to delete image ","messagePattern":"Unable to delete image ","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/src/main/java/org/testcontainers/utility/ResourceReaper.java","lineNumber":315,"sourceCode":"    public void unregisterContainer(String identifier) {\n        registeredContainers.remove(identifier);\n    }\n\n    /**\n     * @deprecated no longer supported API\n     */\n    @Deprecated\n    public void registerImageForCleanup(String dockerImageName) {\n        setHook();\n        registeredImages.add(dockerImageName);\n    }\n\n    private void removeImage(String dockerImageName) {\n        LOGGER.trace(\"Removing image tagged {}\", dockerImageName);\n        try {\n            dockerClient.removeImageCmd(dockerImageName).withForce(true).exec();\n        } catch (Throwable e) {\n            LOGGER.warn(\"Unable to delete image \" + dockerImageName, e);\n        }\n    }\n\n    void setHook() {\n        if (hookIsSet.compareAndSet(false, true)) {\n            // If the JVM stops without containers being stopped, try and stop the container.\n            Runtime\n                .getRuntime()\n                .addShutdownHook(new Thread(DockerClientFactory.TESTCONTAINERS_THREAD_GROUP, this::performCleanup));\n        }\n    }\n\n    /**\n     *\n     * @deprecated internal API\n     */\n    @Deprecated\n    public Map<String, String> getLabels() {","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/testcontainers/testcontainers-java/blob/8e549514e3f01c57d70546fbb8599d138f3903e5/core/src/main/java/org/testcontainers/utility/ResourceReaper.java#L297-L333","documentation":"ResourceReaper.removeImage attempts a forced Docker image removal via dockerClient.removeImageCmd. If removal throws for any reason (image in use, not found, daemon error), it only logs a warning with this message rather than failing. The warning means Testcontainers could not clean up an image it registered for deletion, typically during JVM shutdown cleanup.","triggerScenarios":"An image registered with the ResourceReaper cannot be force-removed: the image is referenced by another running container, it was already removed, the Docker daemon rejects the delete (e.g. child images exist), or the daemon is unreachable at cleanup time.","commonSituations":"JVM shutdown hook cleanup racing with other containers using the same image; manual `docker rmi` removal before Testcontainers cleanup; shared images still in use by containers outside Testcontainers; Docker daemon restarting during test teardown.","solutions":["Check `docker ps -a` for containers still referencing the image and stop them before cleanup","Verify the image name passed to removeImageCmd actually exists (`docker images`); skip cleanup if it was already removed","Inspect the chained exception in the log line for the Docker daemon's actual rejection reason (conflict, in use, etc.)","If this appears at JVM shutdown, it is usually harmless: the daemon's own GC or manual cleanup can remove the image"],"exampleFix":"// before: assuming image cleanup always succeeds\ndockerClient.removeImageCmd(dockerImageName).withForce(true).exec();\n// after: check existence and tolerate already-missing images\nif (!imageExists(dockerImageName)) { return; }\ntry {\n    dockerClient.removeImageCmd(dockerImageName).withForce(true).exec();\n} catch (NotFoundException ignored) { /* already gone */ }","handlingStrategy":"try-catch","validationCode":"boolean exists = dockerClient.listImagesCmd().exec().stream().anyMatch(i -> i.getRepoTags() != null && Arrays.asList(i.getRepoTags()).contains(dockerImageName));","typeGuard":null,"tryCatchPattern":"try { dockerClient.removeImageCmd(name).withForce(true).exec(); } catch (NotFoundException e) { /* already removed */ } catch (Exception e) { log.warn(\"Image cleanup skipped for {}: {}\", name, e.getMessage()); }","preventionTips":["Stop all containers using an image before removing it","Check image existence before removal attempts","Inspect the chained cause in the ResourceReaper warning log","Don't treat shutdown-hook image cleanup warnings as test failures"],"tags":["docker","cleanup","image-removal","warning"],"backgroundTag":"resource-cleanup-failed","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"}