testcontainers / testcontainers/testcontainers-node

withStartupTimeout() is not applied to the port-binding pre-wait (hardcoded 10 s) — measured under CPU contention

Open Beginner friendly
#1,446 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
2.6k
Forks
272
PR merge metrics
No merged PRs in 30d

Description

Problem

GenericContainer.start() waits for the host port bindings to appear (inspectContainerUntilPortsExposed) before the wait strategy runs. That pre-wait has a hardcoded 10 s budget: the util has timeout = 10_000 as a default parameter, and neither call site in generic-container.ts passes this.startupTimeoutMs. So withStartupTimeout(...) only extends the wait strategy; a container whose port binding takes longer than 10 s fails with

Timed out after 10000ms while waiting for container ports to be bound to the host

no matter what startup timeout the caller configured.

This looks like #1281, but I'd like to add a measured data point that is not Kafka/flaky-environment related — the pre-wait itself is the thing that trips, and only under CPU contention.

Measurements (testcontainers 12.1.0, Node 24.19, Docker 29.x, postgres:18-alpine)
  • Local (Apple M3 Pro, one container): host port bound in 1.1–2.6 s.
  • Local, six workspace packages each starting one postgres:18-alpine at the same time (vitest workers): successful starts bound their ports in 2.2–7.2 s; a cold image pull pushed some past 10 s.
  • GitHub Actions ubuntu-latest (2 vCPU, nproc = 2), same six concurrent containers: one start measured 16.7 s until the port was bound — the container was healthy afterwards, it was just slow under load. It failed at 10 s five times in one workflow run although every container had withStartupTimeout(120_000).

So the 10 s default is not "a few milliseconds of Docker Desktop race" in practice: on a loaded host the port binding legitimately takes longer, and the configured startup timeout is the natural budget for it.

Root cause

packages/testcontainers/src/generic-container/generic-container.ts — both calls omit the third argument:

inspectResult = await inspectContainerUntilPortsExposed(() => client.container.inspect(container), container.id);   // reuseContainer
const inspectResult = await inspectContainerUntilPortsExposed(
  () => client.container.inspect(container),
  container.id
);                                                                                                                    // startContainer

inspect-container-util-ports-exposed.ts: timeout = 10_000.

Proposed fix

Pass this.startupTimeoutMs at both call sites. When withStartupTimeout was never called the value is undefined, so the default parameter still yields 10 s — behaviour only changes for callers who explicitly asked for a longer budget. We run exactly this as a pnpm patch since yesterday; the same suite went from 5 pre-wait timeouts per run to 0. PR follows.

Environment
  • testcontainers: 12.1.0 (latest at the time of writing)
  • Node.js: v24.19.0
  • Docker: 29.6.1 (Docker Desktop, arm64) locally; GitHub-hosted ubuntu-latest in CI

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/testcontainers/src/generic-container/generic-container.ts and inspect both calls to inspectContainerUntilPortsExposed, then read packages/testcontainers/src/generic-container/inspect-container-util-ports-exposed.ts to understand its default timeout. Run the existing package suite under concurrent container startup; done means an explicit withStartupTimeout budget covers the pre-wait while callers without one retain the 10-second default.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, node.js, typescript
Domain
devops, testing-qa
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
86/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.