testcontainers/testcontainers-java · warning

An exception while executing the internal check

Error message

An exception while executing the internal check: {}

What it means

InternalCommandPortListeningCheck.call() runs an internal shell command inside the container to check whether ports are listening. If the command's exit code is neither 0 nor 1 (i.e. an unexpected failure such as the command being missing or the container erroring), the raw ExecutableResult is logged with this warning. The check then returns false, which the surrounding wait strategy treats as 'ports not yet listening' until timeout.

Solutions

  1. Inspect the logged result's exit code/stdout to find why the in-container check command failed.
  2. Use a base image with a POSIX shell (/bin/sh) and /proc available so the internal check can execute.
  3. Or switch to ExternalPortListeningCheck-style behavior by ensuring the ports are mapped to the host and used by the wait strategy.
  4. Increase wait timeout only after confirming the container itself stays healthy.

Example fix

// before
new GenericContainer<>("myorg/distroless-app")
    .waitingFor(Wait.forListeningPort()); // internal check fails inside distroless
// after
new GenericContainer<>("myorg/app-with-shell")
    .waitingFor(Wait.forHttp("/health").forStatusCode(200));
Defensive patterns

Strategy: try-catch

Validate before calling

// Prefer images with a POSIX shell; verify before waiting:
Container.ExecResult r = container.execInContainer("sh", "-c", "command -v sh");
if (r.getExitCode() != 0) { /* choose non-internal wait strategy */ }

Try / catch

try {
    container.waitingFor(Wait.forListeningPort()).start();
} catch (ContainerLaunchException | IllegalStateException e) {
    // inspect InternalCommandPortListeningCheck warning for exit code/stdout
}

Prevention

When it happens

Trigger: Executing the internal port-listening check via wait strategies that use InternalCommandPortListeningCheck (e.g. PortListeningCheck / WaitAllStrategy usage) when the in-container command exits with an unexpected code (not 0 or 1), or throws, causing the wrapped IllegalStateException.

Common situations: Containers lacking a shell or /proc/net access (distroless, alpine without sh), containers that stopped during the wait, or images whose shell blocks the check command; users then see the wait strategy time out with this warning beforehand.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheck.java:58

        Instant before = Instant.now();
        try {
            ExecResult result = ExecInContainerPattern.execInContainer(
                waitStrategyTarget.getDockerClient(),
                waitStrategyTarget.getContainerInfo(),
                "/bin/sh",
                "-c",
                command.toString()
            );
            log.trace(
                "Check for {} took {}. Result code '{}', stdout message: '{}'",
                internalPorts,
                Duration.between(before, Instant.now()),
                result.getExitCode(),
                result.getStdout()
            );
            int exitCode = result.getExitCode();
            if (exitCode != 0 && exitCode != 1) {
                log.warn("An exception while executing the internal check: {}", result);
            }
            return exitCode == 0;
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }
}

View on GitHub (pinned to 8e549514e3)