testcontainers/testcontainers-java · error · ContainerLaunchException

Local Docker Compose exited abnormally with code

Error message

Local Docker Compose exited abnormally with code ${exitValue} whilst running command: ${cmd}

What it means

Thrown by LocalDockerCompose.invoke() as a ContainerLaunchException when the docker-compose process runs but exits with a non-zero status (InvalidExitValueException from the executeNoTimeout() call). The message includes the abnormal exit code and the full compose command, meaning the compose invocation itself failed (bad compose file, pull failure, build error, etc.).

Solutions

  1. Read the compose output in the test logs immediately above the exception — it contains the actual docker-compose error; fix that root cause.
  2. Run the same command locally (it is included in the message) in the working directory to reproduce and debug the failure.
  3. Verify the Docker daemon is running and the compose file is valid: `docker info` and `docker-compose -f <file> config`.
  4. Check image names/tags, registry credentials, and port bindings referenced by the compose file in the CI environment.

Example fix

// before: compose file references an image unavailable in CI
services:
  db:
    image: internal-registry/db:latest

// after: pin a pullable tag / add auth
services:
  db:
    image: internal-registry/db:1.4.2
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the compose file before running the container
new ProcessBuilder("docker-compose", "-f", "docker-compose.yml", "config")
    .inheritIO().start().waitFor(); // non-zero => invalid compose file

Try / catch

try {
    composeContainer.start();
} catch (ContainerLaunchException e) {
    if (e.getMessage().contains("exited abnormally")) {
        // message contains the compose command; rerun it for full diagnostics
        throw new IllegalStateException("docker-compose failed: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: DockerComposeContainer.start() driving LocalDockerCompose where `docker-compose up ...` executed in pwd returns a non-zero exitValue — e.g. invalid YAML, missing image, port conflicts, or build failures; caught from org.zeroturnaround.exec's InvalidExitValueException.

Common situations: Compose files referencing images that cannot be pulled (network/registry auth issues); services failing healthchecks so compose exits non-zero; compose file version incompatibilities between the installed binary and the file; Docker daemon not running at all (exit code 1).

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/testcontainers/containers/LocalDockerCompose.java:117

        final List<String> command = Splitter
            .onPattern(" ")
            .omitEmptyStrings()
            .splitToList(this.composeExecutable + " " + cmd);

        try {
            new ProcessExecutor()
                .command(command)
                .redirectOutput(Slf4jStream.of(logger()).asInfo())
                .redirectError(Slf4jStream.of(logger()).asInfo()) // docker-compose will log pull information to stderr
                .environment(environment)
                .directory(pwd)
                .exitValueNormal()
                .executeNoTimeout();

            logger().info("Docker Compose has finished running");
        } catch (InvalidExitValueException e) {
            throw new ContainerLaunchException(
                "Local Docker Compose exited abnormally with code " +
                e.getExitValue() +
                " whilst running command: " +
                cmd
            );
        } catch (Exception e) {
            throw new ContainerLaunchException("Error running local Docker Compose command: " + cmd, e);
        }
    }

    /**
     * @return a logger
     */
    private Logger logger() {
        return DockerLoggerFactory.getLogger(this.composeExecutable);
    }
}

View on GitHub (pinned to 8e549514e3)