testcontainers/testcontainers-java · error · IllegalStateException
copyFileFromContainer can only be used when the Container…
Error message
copyFileFromContainer can only be used when the Container is created.
What it means
copyFileFromContainer reads a file out of the container via the Docker copy-archive API, which requires the container to exist. If getContainerId() is null it throws IllegalStateException — there is no container to copy from yet.
Solutions
- Call start() and let the process complete before copying files out
- Check isCreated()/isRunning() before copying, or guard with getContainerId() != null
- Fix any earlier exception that prevented container startup
- Use execInContainer or wait strategies to ensure the file exists after startup
Example fix
// before
GenericContainer c = new GenericContainer<>("alpine:3");
String content = c.copyFileFromContainer("/tmp/out.txt", is -> new String(is.readAllBytes()));
c.start();
// after
c.start();
String content = c.copyFileFromContainer("/tmp/out.txt", is -> new String(is.readAllBytes())); Defensive patterns
Strategy: validation
Validate before calling
if (container.getContainerId() == null || !container.isRunning()) throw new IllegalStateException("container must be started before copyFileFromContainer"); Try / catch
try { return container.copyFileFromContainer(path, fn); } catch (IllegalStateException e) { if (e.getMessage().contains("copyFileFromContainer")) { throw new IllegalStateException("Forgot to start container before reading " + path, e); } throw e; } Prevention
- Copy files out only in test teardown after the workload ran
- Check container.isRunning() before interacting
- Fail fast on start() exceptions so later copy calls don't confuse the root cause
When it happens
Trigger: Invoking copyFileFromContainer(path, fn) on a container that was never started (or never reached created state), e.g. reading logs/results files in a test before start().
Common situations: Reading an output file produced by the container before the container ran; calling copy on a fresh GenericContainer in a helper; failing start swallowed earlier so the ID was never set.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- copyFileToContainer can only be used with created / running…
- execInContainer can only be used while the Container is…
- Failed to copy Elasticsearch HTTP CA certificate from
- folder-like containerPath in copyFileToContainer is…
AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12).
Data as JSON: /api/errors/d3d2d4fe1c55eb84.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/testcontainers/containers/ContainerState.java:406
inputStream -> {
try (FileOutputStream output = new FileOutputStream(destinationPath)) {
IOUtils.copy(inputStream, output);
return null;
}
}
);
}
/**
* Streams a file which resides inside the container
*
* @param containerPath path to file which is copied from container
* @param function function that takes InputStream of the copied file
*/
@SneakyThrows
default <T> T copyFileFromContainer(String containerPath, ThrowingFunction<InputStream, T> function) {
if (getContainerId() == null) {
throw new IllegalStateException("copyFileFromContainer can only be used when the Container is created.");
}
DockerClient dockerClient = getDockerClient();
try (
InputStream inputStream = dockerClient.copyArchiveFromContainerCmd(getContainerId(), containerPath).exec();
TarArchiveInputStream tarInputStream = new TarArchiveInputStream(inputStream)
) {
tarInputStream.getNextTarEntry();
return function.apply(tarInputStream);
}
}
}
View on GitHub (pinned to 8e549514e3)