testcontainers/testcontainers-java · error · TimeoutException

Expiry time reached before end of output

Error message

Expiry time reached before end of output

What it means

WaitingConsumer.waitUntilEnd() polls the container's log stream until the end is reached or the given expiry (timeout Duration) elapses. If no end-of-output is detected before the deadline it throws a TimeoutException. This means output kept flowing (or the stream never terminated) within the allotted time.

Solutions

  1. Increase the timeout Duration passed to waitUntilEnd().
  2. Use waitUntil(frame -> predicate) with a specific expected line instead of waiting for end-of-output.
  3. Ensure the target container actually terminates if end-of-output is what you need.
  4. Add a `waitUntilEnd` only for batch-style containers that exit.

Example fix

// before
waitingConsumer.waitUntilEnd(Duration.ofSeconds(5), TimeUnit.SECONDS);
// after: wait for a specific log line instead
waitingConsumer.waitUntil(frame -> frame.getUtf8String().contains("Started Application"), 30, TimeUnit.SECONDS);
Defensive patterns

Strategy: try-catch

Try / catch

try { waitingConsumer.waitUntilEnd(60, TimeUnit.SECONDS); } catch (TimeoutException e) { log.warn("container output did not end in time; logs so far: {}", container.getLogs()); }

Prevention

When it happens

Trigger: `waitingConsumer.waitUntilEnd(timeout, ...)` while the container keeps producing output indefinitely, or frames stop but no explicit end condition matches, until the expiry passes.

Common situations: Waiting for a container whose logs keep printing (e.g. tail -f style apps), using waitUntilEnd on a long-running service rather than a batch job, timeout set shorter than the container's startup output burst.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12). Data as JSON: /api/errors/d8d9cb95964b4d9f. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java:157

    private void waitUntilEnd(Long expiry) throws TimeoutException {
        while (System.nanoTime() < expiry) {
            try {
                OutputFrame frame = frames.pollLast(100, TimeUnit.MILLISECONDS);

                if (frame == OutputFrame.END) {
                    return;
                }

                if (frames.isEmpty()) {
                    // sleep for a moment to avoid excessive CPU spinning
                    Thread.sleep(10L);
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        throw new TimeoutException("Expiry time reached before end of output");
    }
}

View on GitHub (pinned to 8e549514e3)