From 2ea51579c23a22d7e3d1e88f967a6182438d1a81 Mon Sep 17 00:00:00 2001 From: Jaiswal-Devpriya Date: Thu, 11 Jun 2026 14:51:03 -0700 Subject: [PATCH] Fallback to amd64 on InternalServerErrorException during image pull --- .../images/RemoteDockerImage.java | 2 +- .../images/RemoteDockerImageTest.java | 36 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/testcontainers/images/RemoteDockerImage.java b/core/src/main/java/org/testcontainers/images/RemoteDockerImage.java index 9d669e46b07..72d5ecb48b5 100644 --- a/core/src/main/java/org/testcontainers/images/RemoteDockerImage.java +++ b/core/src/main/java/org/testcontainers/images/RemoteDockerImage.java @@ -159,7 +159,7 @@ private TimeLimitedLoggedPullImageResultCallback pullImage(PullImageCmd pullImag throws InterruptedException { try { return pullImageCmd.exec(new TimeLimitedLoggedPullImageResultCallback(logger)).awaitCompletion(); - } catch (DockerClientException | NotFoundException e) { + } catch (DockerClientException | NotFoundException | InternalServerErrorException e) { // Try to fallback to x86 return pullImageCmd .withPlatform("linux/amd64") diff --git a/core/src/test/java/org/testcontainers/images/RemoteDockerImageTest.java b/core/src/test/java/org/testcontainers/images/RemoteDockerImageTest.java index 156df3ae7d3..f7d9705af74 100644 --- a/core/src/test/java/org/testcontainers/images/RemoteDockerImageTest.java +++ b/core/src/test/java/org/testcontainers/images/RemoteDockerImageTest.java @@ -1,5 +1,13 @@ package org.testcontainers.images; - +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.command.PullImageCmd; +import com.github.dockerjava.api.exception.InternalServerErrorException; +import org.testcontainers.utility.ImageNameSubstitutor; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.testcontainers.utility.Base58; @@ -76,4 +84,30 @@ protected String resolve() { imageNameFuture.get(); assertThat(remoteDockerImage.toString()).contains("imageName=" + imageName); } + @Test + void fallsBackToAmd64WhenPullFailsWithInternalServerError() throws Exception { + DockerImageName imageName = DockerImageName.parse("test/image:latest"); + DockerClient dockerClient = mock(DockerClient.class); + PullImageCmd pullImageCmd = mock(PullImageCmd.class); + + when(dockerClient.pullImageCmd("test/image")).thenReturn(pullImageCmd); + when(pullImageCmd.withTag("latest")).thenReturn(pullImageCmd); + when(pullImageCmd.withPlatform("linux/amd64")).thenReturn(pullImageCmd); + + when(pullImageCmd.exec(any(TimeLimitedLoggedPullImageResultCallback.class))) + .thenThrow(new InternalServerErrorException("no image found in manifest list for architecture \"arm64\"")) + .thenReturn(mock(TimeLimitedLoggedPullImageResultCallback.class)); + + RemoteDockerImage remoteDockerImage = new RemoteDockerImage( + CompletableFuture.completedFuture(imageName), + __ -> true, + ImageNameSubstitutor.noop(), + dockerClient + ); + + remoteDockerImage.resolve(); + + verify(pullImageCmd).withPlatform("linux/amd64"); + } + }