testcontainers/testcontainers-java · error · IllegalStateException
Failed to process JAR file when extracting classpath…
Error message
Failed to process JAR file when extracting classpath resource: <hostPath>
What it means
MountableFile wraps classpath resources so they can be mounted into containers. When it must extract a resource that lives inside a JAR (e.g. from a fat jar) to a temp location, any IOException while reading the JAR or copying the entry is wrapped in this IllegalStateException. It means Testcontainers could not materialize the classpath resource on the host filesystem, not that the resource itself is necessarily missing (missing resources fail earlier with IllegalArgumentException).
Solutions
- Rebuild the artifact/JAR (mvn clean package or gradle clean build) to rule out a corrupt jar
- Ensure the temp directory (java.io.tmpdir) exists, is writable, and has free space
- Verify the resource exists on the classpath; if it is a directory of files in the jar, confirm the path points to an entry the code can copy
- As a workaround, copy the resource out of the jar yourself and mount it with MountableFile.forHostFile(...)
Example fix
// before
MountableFile.forClasspathResource("config/app.conf"); // fails when inside nested/fat jar
// after
File extracted = extractViaClassloader("config/app.conf"); // write to your own temp file
MountableFile.forHostFile(extracted); Defensive patterns
Strategy: validation
Validate before calling
String path = "config/app.conf";
if (MountableFile.class.getClassLoader().getResource(path) == null)
throw new IllegalStateException("Classpath resource missing: " + path);
// also verify tmpdir is writable:
File tmp = new File(System.getProperty("java.io.tmpdir"));
if (!tmp.canWrite()) throw new IllegalStateException("Temp dir not writable: " + tmp); Type guard
boolean isExtractable(String path) {
URL u = Thread.currentThread().getContextClassLoader().getResource(path);
return u != null && List.of("jar", "file").contains(u.getProtocol());
} Try / catch
try {
MountableFile.forClasspathResource(path);
} catch (IllegalStateException e) {
// fallback: extract manually via classloader and mount a host file
} Prevention
- Prefer running tests from exploded classes directories rather than fat/nested jars
- Check java.io.tmpdir is writable and has disk space in CI
- Rebuild artifacts cleanly before test runs to avoid corrupt jars
When it happens
Trigger: Calling MountableFile.forClasspathResource(...) (directly or via withClasspathResourceMapping / copyFileToContainer) where the resource is inside a JAR, and copyFromJarToLocation throws IOException: corrupt/unreadable JAR, entry is a directory with IO problems, disk full, or temp dir not writable.
Common situations: Running tests from a Spring Boot fat jar or shaded jar where resources are nested jars; read-only or full temp directories; JAR corrupted by partial builds; running under a security manager or restricted filesystem that blocks reading the jar.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Could not load classpath init script
- Can't transfer
- Configured Image Substitutor could not be loaded
- The image requires you to accept a license agreement…
- Resource with path could not be found on any of these…
AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12).
Data as JSON: /api/errors/30f6f5ba50777290.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/testcontainers/utility/MountableFile.java:257
String internalPath = hostPath.replaceAll("[^!]*!/", "");
try (JarFile jarFile = new JarFile(urldecodedJarPath)) {
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
final String name = entry.getName();
if (name.startsWith(internalPath)) {
log.debug(
"Copying classpath resource(s) from {} to {} to permit Docker to bind",
hostPath,
tmpLocation
);
copyFromJarToLocation(jarFile, entry, internalPath, tmpLocation);
}
}
} catch (IOException e) {
throw new IllegalStateException(
"Failed to process JAR file when extracting classpath resource: " + hostPath,
e
);
}
// Mark temporary files/dirs for deletion at JVM shutdown
deleteOnExit(tmpLocation.toPath());
try {
return tmpLocation.getCanonicalPath();
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
private File createTempDirectory() {
try {
if (SystemUtils.IS_OS_MAC) {View on GitHub (pinned to 8e549514e3)