Testcontainers version
4.10.0
Using the latest Testcontainers version?
Yes
Host OS
macOS, Linux
Host arch
arm and x86 respectively
.NET version
10.0.101
Docker version
Client:
Version: 28.4.0
API version: 1.51
Go version: go1.24.7
Git commit: d8eb465
Built: Wed Sep 3 20:56:26 2025
OS/Arch: darwin/arm64
Context: desktop-linux
Server: Docker Desktop 4.46.0 (204649)
Engine:
Version: 28.4.0
API version: 1.51 (minimum version 1.24)
Go version: go1.24.7
Git commit: 249d679
Built: Wed Sep 3 20:58:53 2025
OS/Arch: linux/arm64
Experimental: false
containerd:
Version: 1.7.27
GitCommit: 05044ec0a9a75232cad458027ca83437aae3f4da
runc:
Version: 1.2.5
GitCommit: v1.2.5-0-g59923ef
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Docker info
Client:
Version: 28.4.0
Context: desktop-linux
Debug Mode: false
Plugins:
ai: Docker AI Agent - Ask Gordon (Docker Inc.)
Version: v1.9.11
Path: /Users/adam/.docker/cli-plugins/docker-ai
buildx: Docker Buildx (Docker Inc.)
Version: v0.28.0-desktop.1
Path: /Users/adam/.docker/cli-plugins/docker-buildx
cloud: Docker Cloud (Docker Inc.)
Version: v0.4.27
Path: /Users/adam/.docker/cli-plugins/docker-cloud
compose: Docker Compose (Docker Inc.)
Version: v2.39.2-desktop.1
Path: /Users/adam/.docker/cli-plugins/docker-compose
debug: Get a shell into any image or container (Docker Inc.)
Version: 0.0.42
Path: /Users/adam/.docker/cli-plugins/docker-debug
desktop: Docker Desktop commands (Docker Inc.)
Version: v0.2.0
Path: /Users/adam/.docker/cli-plugins/docker-desktop
extension: Manages Docker extensions (Docker Inc.)
Version: v0.2.31
Path: /Users/adam/.docker/cli-plugins/docker-extension
init: Creates Docker-related starter files for your project (Docker Inc.)
Version: v1.4.0
Path: /Users/adam/.docker/cli-plugins/docker-init
mcp: Docker MCP Plugin (Docker Inc.)
Version: v0.20.0
Path: /Users/adam/.docker/cli-plugins/docker-mcp
model: Docker Model Runner (Docker Inc.)
Version: v0.1.40
Path: /Users/adam/.docker/cli-plugins/docker-model
sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc.)
Version: 0.6.0
Path: /Users/adam/.docker/cli-plugins/docker-sbom
scout: Docker Scout (Docker Inc.)
Version: v1.18.3
Path: /Users/adam/.docker/cli-plugins/docker-scout
WARNING: Plugin "/Users/adam/.docker/cli-plugins/docker-dev" is not valid: failed to fetch metadata: fork/exec /Users/adam/.docker/cli-plugins/docker-dev: no such file or directory
WARNING: Plugin "/Users/adam/.docker/cli-plugins/docker-feedback" is not valid: failed to fetch metadata: fork/exec /Users/adam/.docker/cli-plugins/docker-feedback: no such file or directory
Server:
Containers: 5
Running: 4
Paused: 0
Stopped: 1
Images: 32
Server Version: 28.4.0
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
CDI spec directories:
/etc/cdi
/var/run/cdi
Discovered Devices:
cdi: docker.com/gpu=webgpu
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 05044ec0a9a75232cad458027ca83437aae3f4da
runc version: v1.2.5-0-g59923ef
init version: de40ad0
Security Options:
seccomp
Profile: builtin
cgroupns
Kernel Version: 6.10.14-linuxkit
Operating System: Docker Desktop
OSType: linux
Architecture: aarch64
CPUs: 16
Total Memory: 23.43GiB
Name: docker-desktop
ID: 8f5aaf00-a8a3-4324-bde2-e6a00842c4ce
Docker Root Dir: /var/lib/docker
Debug Mode: false
HTTP Proxy: http.docker.internal:3128
HTTPS Proxy: http.docker.internal:3128
No Proxy: hubproxy.docker.internal
Labels:
com.docker.desktop.address=unix:///Users/adam/Library/Containers/com.docker.docker/Data/docker-cli.sock
Experimental: false
Insecure Registries:
hubproxy.docker.internal:5555
::1/128
127.0.0.0/8
Live Restore Enabled: false
What happened?
Using UntilHttpRequestIsSucceeded against Azure Service Bus Emulator (/health on port 5300) sometimes fails after ~100s with an HttpClient timeout, even when the wait strategy is configured for 3 minutes and many retries.
Expected: wait strategy timeout/retries should be honoured end-to-end (or HTTP client timeout should be configurable/derived from strategy timeout).
Observed: HTTP client timeout appears to preempt strategy timeout.
Minimal setup:
_serviceBusEmulatorContainer = new ServiceBusBuilder("mcr.microsoft.com/azure-messaging/servicebus-emulator:latest")
.WithAcceptLicenseAgreement(true)
.WithPortBinding(5300, true)
.WithWaitStrategy(Wait.ForUnixContainer()
.UntilHttpRequestIsSucceeded(request => request
.ForPath("/health")
.ForPort(5300),
options => options
.WithTimeout(TimeSpan.FromMinutes(3))
.WithInterval(TimeSpan.FromSeconds(2))
.WithRetries(90)))
.Build();
I tried like this, and previously with the generic ContainerBuilder, and without an explicit wait strategy (which I presume defaults to something similar).
Typical failure ends in System.TimeoutException from the wait strategy path after the underlying HTTP request hits its ~100s timeout.
The failure does not happen every time, and single tests usually execute fine. But running a whole test suite, some of them will almost always fail.
My current inelegant workaround is to try/catch the StartAsync and simply retry.
From probing previous issues, I think the issue is here, where the catch is too narrow, not catching exceptions from http timeouts:
https://github.com/testcontainers/testcontainers-dotnet/blob/main/src/Testcontainers/Configurations/WaitStrategies/HttpWaitStrategy.cs#L89
Sample stack trace:
System.Threading.Tasks.TaskCanceledException
The request was canceled due to the configured HttpClient.Timeout of 100 seconds elapsing.
at System.Net.Http.HttpClient.HandleFailure(Exception e, Boolean telemetryStarted, HttpResponseMessage response, CancellationTokenSource cts, CancellationToken cancellationToken, CancellationTokenSource pendingRequestsCts)
at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at DotNet.Testcontainers.Configurations.HttpWaitStrategy.UntilAsync(IContainer container) in /_/src/Testcontainers/Configurations/WaitStrategies/HttpWaitStrategy.cs:line 86
at DotNet.Testcontainers.Containers.DockerContainer.CheckReadinessAsync(WaitStrategy waitStrategy, CancellationToken ct) in /_/src/Testcontainers/Containers/DockerContainer.cs:line 712
at DotNet.Testcontainers.Containers.DockerContainer.CheckReadinessAsync(WaitStrategy waitStrategy, CancellationToken ct) in /_/src/Testcontainers/Containers/DockerContainer.cs:line 721
at DotNet.Testcontainers.Configurations.WaitStrategy.<>c__DisplayClass29_0.<<WaitUntilAsync>g__UntilAsync|0>d.MoveNext() in /_/src/Testcontainers/Configurations/WaitStrategies/WaitStrategy.cs:line 197
Testcontainers version
4.10.0
Using the latest Testcontainers version?
Yes
Host OS
macOS, Linux
Host arch
arm and x86 respectively
.NET version
10.0.101
Docker version
Client: Version: 28.4.0 API version: 1.51 Go version: go1.24.7 Git commit: d8eb465 Built: Wed Sep 3 20:56:26 2025 OS/Arch: darwin/arm64 Context: desktop-linux Server: Docker Desktop 4.46.0 (204649) Engine: Version: 28.4.0 API version: 1.51 (minimum version 1.24) Go version: go1.24.7 Git commit: 249d679 Built: Wed Sep 3 20:58:53 2025 OS/Arch: linux/arm64 Experimental: false containerd: Version: 1.7.27 GitCommit: 05044ec0a9a75232cad458027ca83437aae3f4da runc: Version: 1.2.5 GitCommit: v1.2.5-0-g59923ef docker-init: Version: 0.19.0 GitCommit: de40ad0Docker info
What happened?
Using UntilHttpRequestIsSucceeded against Azure Service Bus Emulator (/health on port 5300) sometimes fails after ~100s with an HttpClient timeout, even when the wait strategy is configured for 3 minutes and many retries.
Expected: wait strategy timeout/retries should be honoured end-to-end (or HTTP client timeout should be configurable/derived from strategy timeout).
Observed: HTTP client timeout appears to preempt strategy timeout.
Minimal setup:
I tried like this, and previously with the generic
ContainerBuilder, and without an explicit wait strategy (which I presume defaults to something similar).Typical failure ends in System.TimeoutException from the wait strategy path after the underlying HTTP request hits its ~100s timeout.
The failure does not happen every time, and single tests usually execute fine. But running a whole test suite, some of them will almost always fail.
My current inelegant workaround is to try/catch the
StartAsyncand simply retry.From probing previous issues, I think the issue is here, where the catch is too narrow, not catching exceptions from http timeouts:
https://github.com/testcontainers/testcontainers-dotnet/blob/main/src/Testcontainers/Configurations/WaitStrategies/HttpWaitStrategy.cs#L89
Sample stack trace: