testcontainers/testcontainers-java · error · ShellCommandException
Exception when executing
Error message
Exception when executing ${joinedCommand} What it means
CommandLine.runShellCommand executes an external command via ProcessExecutor and returns its UTF-8 stdout. When the command fails to run or complete — non-zero exit (InvalidExitValueException), timeout, I/O error, or interruption — it wraps the cause in ShellCommandException including the joined command line. It signals that an external helper binary could not be executed successfully.
Solutions
- Run the joined command from the message manually in a shell to reproduce and see the real failure.
- Install the missing binary or fix PATH so the command resolves.
- Fix the command so it exits 0 (or check why Testcontainers calls it); ensure the environment is non-interactive.
- Check for JVM shutdown/thread interruption if the cause is InterruptedException.
Defensive patterns
Strategy: try-catch
Validate before calling
// verify the external command exists before Testcontainers calls it
Process which = new ProcessBuilder("which", "<tool>").start();
if (which.waitFor() != 0) throw new IllegalStateException("<tool> not on PATH"); Try / catch
try {
String out = CommandLine.runShellCommand(cmd...);
} catch (ShellCommandException e) {
log.error("External command failed: {} cause: {}", e.getMessage(), e.getCause());
// fall back or rethrow with environment guidance
} Prevention
- Install and PATH-export any CLIs the library shells out to
- Run commands in CI before tests to fail fast
- Avoid interrupting JVM/threads during container startup
- Check exit codes by reproducing the command manually
When it happens
Trigger: Any Testcontainers path invoking a local command (e.g. docker-machine/other CLI probes) where the binary is missing, exits non-zero, hangs past the timeout, or the JVM thread is interrupted.
Common situations: Required CLI not installed or not on PATH; script with non-zero exit; slow machine hitting the process timeout; command prompting for input; shutdown interrupts mid-execution.
Related errors
AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12).
Data as JSON: /api/errors/21dda718a06e4fc9.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/testcontainers/utility/CommandLine.java:40
private static final Logger LOGGER = LoggerFactory.getLogger(CommandLine.class);
/**
* Run a shell command synchronously.
*
* @param command command to run and arguments
* @return the stdout output of the command
*/
public static String runShellCommand(String... command) {
String joinedCommand = String.join(" ", command);
LOGGER.debug("Executing shell command: `{}`", joinedCommand);
try {
ProcessResult result = new ProcessExecutor().command(command).readOutput(true).exitValueNormal().execute();
return result.outputUTF8().trim();
} catch (IOException | InterruptedException | TimeoutException | InvalidExitValueException e) {
throw new ShellCommandException("Exception when executing " + joinedCommand, e);
}
}
/**
* Check whether an executable exists, either at a specific path (if a full path is given) or
* on the PATH.
*
* @param executable the name of an executable on the PATH or a complete path to an executable that may/may not exist
* @return whether the executable exists and is executable
*/
public static boolean executableExists(String executable) {
// First check if we've been given the full path already
File directFile = new File(executable);
if (directFile.exists() && directFile.canExecute()) {
return true;
}
for (String pathString : getSystemPath()) {View on GitHub (pinned to 8e549514e3)