{"record":{"id":"141b3d0006fd2817","repo":"testcontainers/testcontainers-java","slug":"execincontainer-can-only-be-used-while-the-container-is","errorCode":null,"errorMessage":"execInContainer can only be used while the Container is running","messagePattern":"execInContainer can only be used while the Container is running","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/testcontainers/containers/ExecInContainerPattern.java","lineNumber":196,"sourceCode":"     * @throws IOException if there's an issue communicating with Docker\n     * @throws InterruptedException if the thread waiting for the response is interrupted\n     * @throws UnsupportedOperationException if the docker daemon you're connecting to doesn't support \"exec\".\n     */\n    public Container.ExecResult execInContainer(\n        DockerClient dockerClient,\n        InspectContainerResponse containerInfo,\n        Charset outputCharset,\n        ExecConfig execConfig\n    ) throws UnsupportedOperationException, IOException, InterruptedException {\n        if (!TestEnvironment.dockerExecutionDriverSupportsExec()) {\n            // at time of writing, this is the expected result in CircleCI.\n            throw new UnsupportedOperationException(\n                \"Your docker daemon is running the \\\"lxc\\\" driver, which doesn't support \\\"docker exec\\\".\"\n            );\n        }\n\n        if (!isRunning(containerInfo)) {\n            throw new IllegalStateException(\"execInContainer can only be used while the Container is running\");\n        }\n\n        String containerId = containerInfo.getId();\n        String containerName = containerInfo.getName();\n\n        String[] command = execConfig.getCommand();\n        log.debug(\"{}: Running \\\"exec\\\" command: {}\", containerName, String.join(\" \", command));\n        final ExecCreateCmd execCreateCmd = dockerClient\n            .execCreateCmd(containerId)\n            .withAttachStdout(true)\n            .withAttachStderr(true)\n            .withCmd(command);\n\n        String user = execConfig.getUser();\n        if (user != null && !user.isEmpty()) {\n            log.debug(\"{}: Running \\\"exec\\\" command with user: {}\", containerName, user);\n            execCreateCmd.withUser(user);\n        }","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/testcontainers/testcontainers-java/blob/8e549514e3f01c57d70546fbb8599d138f3903e5/core/src/main/java/org/testcontainers/containers/ExecInContainerPattern.java#L178-L214","documentation":"Testcontainers throws this IllegalStateException from ExecInContainerPattern.execInContainer when you attempt to run a command inside a container that is not in the running state. Docker's exec API only works against a live container, so the library validates the container state (via the cached InspectContainerResponse) before calling it and fails fast with a clear message instead of an obscure Docker API error.","triggerScenarios":"Calling container.execInContainer(\"cmd\") (or execInContainer(WaitStrategies variant) with a charset/timeout) before container.start() has completed, after container.stop() has been called, or from a different thread while the container is concurrently being stopped; also when the container already exited/crashed but the test still tries to exec into it.","commonSituations":"Tests that exec a setup command in @BeforeAll before the container is started; using execInContainer in @AfterAll after stop(); JUnit reusing a container across tests where a previous test stopped it; containers whose process exited early (e.g. bad entrypoint) so isRunning() is false by the time the exec runs.","solutions":["Ensure container.start() has completed before calling execInContainer (e.g. move the exec into the test method or after startup callbacks).","Do not call stop() on the container before the exec; check lifecycle ordering in @BeforeAll/@AfterAll.","Guard the call with container.isRunning() and skip or start the container as needed.","If the container is exiting on its own, fix the container's command/entrypoint so it stays alive (e.g. keep the main process in the foreground)."],"exampleFix":"// before\ncontainer.execInContainer(\"sh\", \"-c\", \"load-data.sh\"); // may run before start\n// after\ncontainer.start();\nif (container.isRunning()) {\n    container.execInContainer(\"sh\", \"-c\", \"load-data.sh\");\n}","handlingStrategy":"validation","validationCode":"if (!container.isRunning()) {\n    container.start();\n}\ncontainer.execInContainer(\"sh\", \"-c\", \"setup.sh\");","typeGuard":"boolean canExec(GenericContainer<?> c) { return c.isRunning(); }","tryCatchPattern":"try {\n    container.execInContainer(\"cmd\");\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"only be used while the Container is running\")) {\n        container.start();\n        container.execInContainer(\"cmd\");\n    } else throw e;\n}","preventionTips":["Call execInContainer only after start() completes or inside a wait-strategy callback.","Never stop the container earlier in @AfterAll/@BeforeEach than the last exec.","Use container.isRunning() as a cheap pre-check."],"tags":["docker","container-lifecycle","illegal-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"8e549514e3f01c57d70546fbb8599d138f3903e5","analyzedAt":"2026-09-12T14:56:41.227Z","contentChangedAt":"2026-09-12T14:56:41.227Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}