Skip to content

[Bug]: BasicWaitStrategies() gives false-positive ready signal on reused containers #3671

@aartal

Description

@aartal

Testcontainers version

v0.42.0

Using the latest Testcontainers version?

Yes

Host OS

Mac

Host arch

ARM

Go version

1.26.2

Docker version

Client: Docker Engine - Community
 Version:           29.4.0
 API version:       1.51 (downgraded from 1.54)
 Go version:        go1.26.1
 Git commit:        9d7ad9ff18
 Built:             Fri Apr  3 14:24:17 2026
 OS/Arch:           darwin/arm64
 Context:           default

Server: Docker Engine - Community
 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:55 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: Docker Engine - Community
 Version:    29.4.0
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.9.1
    Path:     /Users/myuser/.docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.23.0
    Path:     /Users/myuser/.docker/cli-plugins/docker-compose

Server:
 Containers: 29
  Running: 3
  Paused: 0
  Stopped: 26
 Images: 23
 Server Version: 28.4.0
 Storage Driver: overlayfs
  driver-type: io.containerd.snapshotter.v1
 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
 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:
  apparmor
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version: 6.8.0-64-generic
 Operating System: Ubuntu 24.04.2 LTS
 OSType: linux
 Architecture: aarch64
 CPUs: 2
 Total Memory: 5.773GiB
 Name: colima
 ID: b8a2f8ea-f188-4303-8f69-728eea673892
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  ::1/128
  127.0.0.0/8
 Live Restore Enabled: false
 Firewall Backend: iptable

What happened?

When using testcontainers-go/modules/postgres with container reuse (testcontainers.WithReuseByName), postgres.BasicWaitStrategies() can return a false-positive ready signal, causing tests to fail non-deterministically.

BasicWaitStrategies() relies on wait.ForLog("database system is ready to accept connections").WithOccurrence(2). On a reused container, the log stream includes output from the previous run. If testcontainers reads stale logs before the current postgres process emits its own ready messages, the occurrence count is satisfied immediately — while postgres is still mid-startup.

Reproduction

  1. Use testcontainers-go/modules/postgres with testcontainers.WithReuseByName
  2. Use postgres.BasicWaitStrategies() as the wait strategy
  3. Run tests more than once — on the second run the container is reused
  4. Observe intermittent failures where tests attempt to connect before postgres is ready

Expected behaviour

BasicWaitStrategies() should be safe to use with container reuse, or the documentation should warn that it is not.

Actual behaviour

Log-based wait strategies can match against stale logs from a previous container lifecycle, giving a false-positive ready signal.

Context

A previous attempt to document ForSQL as a safer alternative was made in #2208. That approach avoids the stale-log problem by actually dialing postgres, but was not merged. Revisiting that recommendation — or fixing BasicWaitStrategies() to skip logs older than the current container start time — would resolve this.

Version

First observed in v0.42.0. Not reproduced locally in v0.41.0, though the race is timing-dependent and may exist there too. v0.42.0 includes a change to the log streaming infrastructure (migration to moby modules, #3591) which may make the race more likely to surface.

Relevant log output

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugAn issue with the library

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions