quarkusio/quarkus · error · IOException
Bad ZIP entry: ${target}
Error message
Bad ZIP entry: ${target} What it means
DevModeTask.extractDevModeClasses throws this IOException when extracting entries from an application jar in dev mode would write outside the target module classes directory. After resolving and normalizing the ZIP entry name against moduleClasses, any entry whose normalized path does not start with moduleClasses is treated as a path traversal (zip-slip) attack and rejected.
Source
Thrown at core/deployment/src/main/java/io/quarkus/deployment/mutability/DevModeTask.java:166
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
throw exc;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
});
} else {
try (ZipInputStream fs = new ZipInputStream(Files.newInputStream(p))) {
ZipEntry entry = fs.getNextEntry();
while (entry != null) {
Path target = moduleClasses.resolve(entry.getName()).normalize();
if (!target.startsWith(moduleClasses)) {
throw new IOException("Bad ZIP entry: " + target);
}
if (entry.getName().endsWith("/")) {
Files.createDirectories(target);
} else {
if (!Files.exists(target)) {
// make sure the parent directories are created first
// META-INF/MANIFEST.MF is often written first,
// even before META-INF is written probably due to
// https://bugs.openjdk.java.net/browse/JDK-8031748
Files.createDirectories(target.getParent());
try (OutputStream out = Files.newOutputStream(target)) {
IoUtils.copy(out, fs);
}
}
}
entry = fs.getNextEntry();
}View on GitHub (pinned to e1c734241f)
Solutions
- Delete the stale/corrupt jar (typically under target/ or the dev-mode application directory) and rebuild with ./mvnw clean install -DskipTests.
- Inspect the jar contents (unzip -l) to find the entry with ../ or absolute-path components and identify which artifact produced it.
- Ensure no custom build step or shading plugin writes entries with path-traversal names.
Example fix
// inspect and rebuild $ unzip -l target/quarkus-app/... | grep '\.\.' $ ./mvnw clean install -DskipTests # then restart dev mode $ ./mvnw quarkus:dev
Defensive patterns
Strategy: validation
Validate before calling
try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(jar))) {
ZipEntry e;
while ((e = zis.getNextEntry()) != null) {
Path t = moduleClasses.resolve(e.getName()).normalize();
if (!t.startsWith(moduleClasses)) throw new IllegalStateException("Unsafe entry: " + e.getName());
}
} Try / catch
try {
extractDevModeClasses(...);
} catch (IOException e) {
if (e.getMessage().startsWith("Bad ZIP entry")) {
throw new IllegalStateException("Corrupt/malicious jar in dev-mode state; run mvn clean and rebuild", e);
}
throw e;
} Prevention
- Run mvn clean after suspicious build failures to remove stale jars.
- Scan dependency jars for entries containing ../ or absolute paths.
- Keep the build pipeline and shading configuration from writing unusual entry names.
When it happens
Trigger: Starting dev mode with an application jar (in the quarkus application dev-mode dir) containing a ZIP entry with a name like ../../foo.class or an absolute path; extraction resolves outside moduleClasses and throws.
Common situations: A corrupted or maliciously crafted jar in local dev-mode state; stale jars from a previous build replaced by artifacts with odd entry names; running dev mode against jars produced by a broken build pipeline.
Related errors
- Unable to deserialize the dev mode context. Does the Quarkus
- Hot deployment of the application is not supported when upda
- remote-dev can only be used with mutable applications i.e. u
- Failed to create compiler
- Failed to open class path file <file>
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/3214cafe4a1e0f4b.
Report an issue: GitHub.