testcontainers/testcontainers-java · error · IllegalStateException

Wait strategy failed. Container crashed

Error message

Wait strategy failed. Container crashed: ${error}

What it means

When the wait strategy fails, tryStart reads the container's state.error field (Docker's error string for the container, e.g. from a failed entrypoint exec) and, if non-blank, throws this IllegalStateException including that error text. It surfaces Docker's own description of the crash as the message.

Solutions

  1. Read the Docker error embedded in the message — it names the missing binary or runtime problem.
  2. Fix the command/entrypoint path so it exists in the image, or add the file.
  3. Use an image matching the host architecture (or enable emulation) to avoid 'exec format error'.
  4. Check file permissions on any script used as entrypoint (chmod +x, correct shebang).

Example fix

// before
new GenericContainer<>("alpine").withCommand("/app/start.sh"); // OCI error: no such file
// after
new GenericContainer<>("alpine").withCommand("sh", "/app/start.sh"); // or add the script to the image
Defensive patterns

Strategy: validation

Validate before calling

// verify the entrypoint exists and is executable in the image:
// docker run --rm --entrypoint ls <image> -l /path/to/cmd

Type guard

null

Try / catch

try {
    container.start();
} catch (ContainerLaunchException e) {
    // message contains Docker's state.error (e.g. 'OCI runtime create failed') — read it
    throw e;
}

Prevention

When it happens

Trigger: Docker records an error on the container state — commonly 'OCI runtime create failed ... no such file or directory' for a missing binary/script in the command, or exec format errors for wrong-architecture images — while the wait strategy was pending.

Common situations: withCommand() pointing at a file that doesn't exist in the image; pulling an arm64 image on x86 (exec format error); bad entrypoint permissions; malformed volume mounts breaking the runtime.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/testcontainers/containers/GenericContainer.java:515

                if (inspectContainerResponse == null) {
                    throw new IllegalStateException("Wait strategy failed. Container is removed", e);
                }

                InspectContainerResponse.ContainerState state = inspectContainerResponse.getState();
                if (Boolean.TRUE.equals(state.getDead())) {
                    throw new IllegalStateException("Wait strategy failed. Container is dead", e);
                }

                if (Boolean.TRUE.equals(state.getOOMKilled())) {
                    throw new IllegalStateException(
                        "Wait strategy failed. Container crashed with out-of-memory (OOMKilled)",
                        e
                    );
                }

                String error = state.getError();
                if (!StringUtils.isBlank(error)) {
                    throw new IllegalStateException("Wait strategy failed. Container crashed: " + error, e);
                }

                if (!Boolean.TRUE.equals(state.getRunning())) {
                    throw new IllegalStateException(
                        "Wait strategy failed. Container exited with code " + state.getExitCode(),
                        e
                    );
                }

                throw e;
            }

            logger().info("Container {} started in {}", dockerImageName, Duration.between(startedAt, Instant.now()));
            containerIsStarted(containerInfo, reused);
        } catch (Exception e) {
            if (e instanceof UndeclaredThrowableException && e.getCause() instanceof Exception) {
                e = (Exception) e.getCause();
            }

View on GitHub (pinned to 8e549514e3)