testcontainers/testcontainers-java · error · IllegalStateException
Changing startup timeout is not supported with mode
Error message
Changing startup timeout is not supported with mode %s
What it means
WaitAllStrategy in Mode.WITH_INDIVIDUAL_TIMEOUTS_ONLY lets each inner wait strategy own its timeout; the outer strategy therefore forbids overriding a global one. Calling withStartupTimeout on such an instance throws this IllegalStateException at configuration time (before any container starts).
Solutions
- Remove the withStartupTimeout call and set timeouts on each child strategy instead
- Use WaitAllStrategy.Mode.WITH_OUTER_TIMEOUT (default) if you want a single global timeout
- Wrap construction in your own helper so the timeout call is only applied for compatible modes
Example fix
// before
new WaitAllStrategy<>(WaitAllStrategy.Mode.WITH_INDIVIDUAL_TIMEOUTS_ONLY)
.withStrategy(new HttpWaitStrategy().withStartupTimeout(Duration.ofSeconds(30)))
.withStartupTimeout(Duration.ofSeconds(90));
// after
new WaitAllStrategy<>(WaitAllStrategy.Mode.WITH_INDIVIDUAL_TIMEOUTS_ONLY)
.withStrategy(new HttpWaitStrategy().withStartupTimeout(Duration.ofSeconds(30))); Defensive patterns
Strategy: validation
Validate before calling
WaitAllStrategy<WaitStrategy> s = new WaitAllStrategy<>(WaitAllStrategy.Mode.WITH_INDIVIDUAL_TIMEOUTS_ONLY);
// Only call withStartupTimeout when the mode permits it
if (mode != WaitAllStrategy.Mode.WITH_INDIVIDUAL_TIMEOUTS_ONLY) {
s.withStartupTimeout(Duration.ofSeconds(90));
} Try / catch
try {
return allStrategy.withStartupTimeout(timeout);
} catch (IllegalStateException e) {
if (e.getMessage().contains("Changing startup timeout is not supported")) {
return allStrategy; // keep per-child timeouts
}
throw e;
} Prevention
- Set timeouts on child strategies when using WITH_INDIVIDUAL_TIMEOUTS_ONLY
- Never chain a shared builder that unconditionally calls withStartupTimeout
- Default mode (WITH_OUTER_TIMEOUT) is the safe choice when you want one global timeout
When it happens
Trigger: new WaitAllStrategy<>(WaitAllStrategy.Mode.WITH_INDIVIDUAL_TIMEOUTS_ONLY).withStartupTimeout(Duration.ofSeconds(90)) — or builder chaining that applies withStartupTimeout after selecting that mode.
Common situations: Copy-pasting a shared wait-strategy builder that always sets withStartupTimeout; switching the mode constant without removing the timeout call; combining per-strategy timeouts configured on children with an accidental global one.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Timed out waiting for URL to be accessible
- Timed out waiting for log output matching
- Timed out waiting for container to execute
- Services named do not exist, but wait conditions have been…
- Timed out waiting for container to become healthy
AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12).
Data as JSON: /api/errors/ff1a61e0a410141e.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/testcontainers/containers/wait/strategy/WaitAllStrategy.java:82
private void waitUntilNestedStrategiesAreReady(WaitStrategyTarget waitStrategyTarget) {
for (WaitStrategy strategy : strategies) {
strategy.waitUntilReady(waitStrategyTarget);
}
}
public WaitAllStrategy withStrategy(WaitStrategy strategy) {
if (mode == Mode.WITH_OUTER_TIMEOUT) {
applyStartupTimeout(strategy);
}
this.strategies.add(strategy);
return this;
}
@Override
public WaitAllStrategy withStartupTimeout(Duration startupTimeout) {
if (mode == Mode.WITH_INDIVIDUAL_TIMEOUTS_ONLY) {
throw new IllegalStateException(
String.format(
"Changing startup timeout is not supported with mode %s",
Mode.WITH_INDIVIDUAL_TIMEOUTS_ONLY
)
);
}
this.timeout = startupTimeout;
strategies.forEach(this::applyStartupTimeout);
return this;
}
private void applyStartupTimeout(WaitStrategy childStrategy) {
childStrategy.withStartupTimeout(this.timeout);
}
}
View on GitHub (pinned to 8e549514e3)