quarkusio/quarkus · error · RuntimeException
Unable to read
Error message
Unable to read
What it means
Thrown by PathTreeClassPathElement.getData() when the bytes of a classpath resource cannot be read from its containing JAR. The library wraps the underlying IOException (e.g. ZipException) in a RuntimeException, either after attempting to re-open a jar whose file handle went stale, or directly when reading fails.
Source
Thrown at independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/PathTreeClassPathElement.java:325
lock.readLock().lock();
}
}
} catch (IOException e) {
if (pathTree.isOpen()) {
//this is a weird corner case, that should not really affect end users, but is super annoying
//if you are actually working on Quarkus. If you rebuild quarkus while you have an application
//running reading from the rebuilt zip file will fail, but some of these classes are needed
//for a clean shutdown, so the Java process hangs and needs to be forcibly killed
//this effectively attempts to reopen the file, allowing shutdown to work.
//we need to do this here as close needs a write lock while withJarFile takes a readLock
log.error("Failed to read " + name
+ " attempting to re-open the zip file. It is likely a jar file changed on disk, you should shutdown your application",
e);
lock.readLock().unlock();
try {
close();
} catch (IOException ignore) {
throw new RuntimeException("Unable to read " + name, e.getCause());
} finally {
lock.readLock().lock();
}
} else {
throw new RuntimeException("Unable to read " + name, e);
}
}
}
// reading the entry directly from the JAR
final boolean interrupted = Thread.interrupted();
try {
return pathTree.getOriginalTree().apply(name, visit -> {
if (visit == null) {
return null;
}
try {
return Files.readAllBytes(visit.getPath());
} catch (IOException e) {View on GitHub (pinned to e1c734241f)
Solutions
- Stop the running application, rebuild, and start it again so the classloader picks up the fresh jar
- Identify which process or build step is rewriting the jar while the app runs and serialize them (e.g. don't run 'mvn install' on a jar used by a live dev-mode app)
- If the error persists on a stable jar, verify the jar's integrity (jar tf / unzip -t) and rebuild it
- Restart dev-mode if an external build (e.g. IDE) touched target/ jars mid-run
Example fix
// before (external process overwrote jar while app runs) mvn install & ./mvnw quarkus:dev # reads jar concurrently -> Unable to read // after ./mvnw install ./mvnw quarkus:dev # build finishes before dev mode starts
Defensive patterns
Strategy: retry
Validate before calling
Path jar = Paths.get(jarPath);
if (!Files.isRegularFile(jar) || !Files.isReadable(jar)) {
throw new IllegalStateException("Jar missing/unreadable: " + jar);
}
try (var zf = new java.util.zip.ZipFile(jar.toFile())) {
if (zf.getEntry(resourceName) == null) throw new IllegalStateException("Entry missing: " + resourceName);
} Try / catch
try {
byte[] data = element.getData(resourceName);
} catch (RuntimeException e) {
// message starts with "Unable to read " — jar likely changed on disk
// restart the application / recreate the classloader, do not retry in-place
} Prevention
- Never rebuild or overwrite jars that a running Quarkus dev-mode/test process has open
- Run external builds before starting dev mode, not concurrently
- Use a stable filesystem for classpath jars (avoid NFS/container bind-mount churn for target/)
When it happens
Trigger: Calling getData() on a classpath element backed by a jar file that was modified, replaced, or deleted on disk while the classloader held it open (the code detects a changed jar, tries close() + re-open, and gives up if that still fails), or an IOException reading the zip entry.
Common situations: Rebuilding/redeploying a jar while a dev-mode or test application is still running; Maven/Gradle overwriting the jar during a build; file-sync in a container or NFS causing the jar inode to change; corrupted or partially-written jar files.
Related errors
- Classloader is not resettable
- Failed to load steps from %s
- The class (${name}) cannot be created during deployment.
- Cannot find ClassLoadingRecorder.class on classpath
- Failed to load the condition class ${testClassName} for capa
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/2ea4941e251ec0a7.
Report an issue: GitHub.