testcontainers/testcontainers-java · critical · ContainerLaunchException

Could not create/start container

Error message

Could not create/start container

What it means

This is the outermost wrapper in tryStart: after logging the container's stdout/stderr and calling stop() for cleanup, any exception from container creation/start (including all the IllegalStateExceptions above, and unknown failures) is rethrown as ContainerLaunchException('Could not create/start container'). The cause chain contains the precise reason.

Solutions

  1. Always inspect the 'Caused by' chain of this exception — the root cause is there.
  2. Verify Docker is running and reachable (docker info) and TESTCONTAINERS_* env/properties are sane.
  3. Review the container logs printed immediately above the stack trace for the app-level failure.
  4. Check for port conflicts and fix withCommand port or use withExposedPorts/withRandomPorts.
  5. If the image pull fails, authenticate to the registry or verify the image reference.

Example fix

// before
} catch (Exception e) {
    e.printStackTrace(); // loses the structured cause chain context
}
// after
} catch (ContainerLaunchException e) {
    Throwable root = e;
    while (root.getCause() != null) root = root.getCause();
    logger.error("Container failed to start, root cause: {}", root.getMessage(), e);
    throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight before tests:
Process p = new ProcessBuilder("docker", "info").start();
boolean dockerReady = p.waitFor(10, java.util.concurrent.TimeUnit.SECONDS) && p.exitValue() == 0;

Type guard

null

Try / catch

try {
    container.start();
} catch (ContainerLaunchException e) {
    // this is the outer wrapper — walk the cause chain to the root
    Throwable t = e;
    while (t.getCause() != null) t = t.getCause();
    logger.error("Root cause: {}", t.getMessage(), e);
    throw e;
}

Prevention

When it happens

Trigger: Any failure during container.start(): image pull errors, Docker daemon unreachable, create command rejection by the daemon (e.g. invalid host config, port conflicts), startup check or wait strategy failures, or errors in containerIsStarting hooks.

Common situations: Docker not installed/running on the dev machine or CI; port binding conflicts (address already in use); invalid withCreateContainerCmdModifier settings rejected by the daemon; network/rate limits failing the image pull.

Related errors


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

Appendix: source

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

            }
            if (e instanceof InvocationTargetException && e.getCause() instanceof Exception) {
                e = (Exception) e.getCause();
            }
            logger().error("Could not start container", e);

            if (containerId != null) {
                // Log output if startup failed, either due to a container failure or exception (including timeout)
                final String containerLogs = getLogs();

                if (containerLogs.length() > 0) {
                    logger().error("Log output from the failed container:\n{}", containerLogs);
                } else {
                    logger().error("There are no stdout/stderr logs available for the failed container");
                }
                stop();
            }

            throw new ContainerLaunchException("Could not create/start container", e);
        }
    }

    @VisibleForTesting
    Checksum hashCopiedFiles() {
        Checksum checksum = new Adler32();
        Stream
            .of(copyToFileContainerPathMap, copyToTransferableContainerPathMap)
            .flatMap(it -> it.entrySet().stream())
            .sorted(Entry.comparingByValue())
            .forEach(entry -> {
                byte[] pathBytes = entry.getValue().getBytes();
                // Add path to the hash
                checksum.update(pathBytes, 0, pathBytes.length);

                entry.getKey().updateChecksum(checksum);
            });
        return checksum;

View on GitHub (pinned to 8e549514e3)