HMCL-dev/HMCL · error · ZipException
Not a zip file
Error message
Not a zip file
What it means
When the jdk.zipfs provider exists but the file cannot be mounted as a zip filesystem, the underlying provider signals UnsupportedOperationException, which createZipFileSystem translates into a ZipException with the message 'Not a zip file'. This is the API-level signal that the target file is not a valid zip archive.
Solutions
- Verify the file is a real zip: check the PK magic bytes or open it with java.util.zip.ZipFile first.
- Re-download or re-extract the archive; validate its checksum against the source.
- Catch ZipException around createReadOnlyZipFileSystem/createWritableZipFileSystem and report the file as corrupt/unsupported to the user.
Example fix
// before
FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(path); // ZipException on junk
// after
try (ZipFile zf = new ZipFile(path.toFile())) {
FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(path);
} catch (ZipException e) {
throw new IOException("Invalid or corrupted zip: " + path, e);
} Defensive patterns
Strategy: validation
Validate before calling
static void requireZip(Path p) throws IOException {
try (DataInputStream in = new DataInputStream(Files.newInputStream(p))) {
if (in.readInt() != 0x504B0304) throw new IOException("Not a zip file: " + p);
}
} Try / catch
try { return CompressingUtils.createReadOnlyZipFileSystem(path); } catch (ZipException e) { log.warn("Not a zip file: " + path, e); throw new InvalidArchiveException(path, e); } Prevention
- Validate zip magic bytes before mounting zip filesystems.
- Verify download integrity (size/checksum) before use.
- Do not trust file extensions; treat .zip as untrusted input.
When it happens
Trigger: Calling createZipFileSystem (via createReadOnlyZipFileSystem or createWritableZipFileSystem) on a path that is not a zip archive — wrong file, corrupted data, or a different compression format (e.g. gzip, tar) renamed to .zip.
Common situations: Pointing mod/installer code at a partially downloaded or HTML error page saved as .zip; archives created by non-zip tools; truncated downloads.
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
- Theme pack does not contain
- Theme-pack entry name is not normalized
- Theme-pack entry is empty
- Theme-pack entry contains a control character
- Cannot export a background directory as a theme-pack asset
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/95e39718bf523f33.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/CompressingUtils.java:242
public static FileSystem createWritableZipFileSystem(Path zipFile, Charset charset) throws IOException {
return createZipFileSystem(zipFile, true, true, charset);
}
public static FileSystem createZipFileSystem(Path zipFile, boolean create, boolean useTempFile, Charset encoding) throws IOException {
Map<String, Object> env = new HashMap<>();
if (create)
env.put("create", "true");
if (encoding != null)
env.put("encoding", encoding.name());
if (useTempFile)
env.put("useTempFile", true);
try {
if (ZIPFS_PROVIDER == null)
throw new FileSystemNotFoundException("Module jdk.zipfs does not exist");
return ZIPFS_PROVIDER.newFileSystem(zipFile, env);
} catch (UnsupportedOperationException ex) {
throw new ZipException("Not a zip file");
} catch (FileSystemNotFoundException ex) {
throw Lang.apply(new ZipException("Java Environment is broken"), it -> it.initCause(ex));
}
}
/**
* Read the text content of a file in zip.
*
* @param zipFile the zip file
* @param name the location of the text in zip file, something like A/B/C/D.txt
* @return the plain text content of given file.
* @throws IOException if the file is not a valid zip file.
*/
public static String readTextZipEntry(Path zipFile, String name) throws IOException {
try (ZipArchiveReader s = new ZipArchiveReader(zipFile)) {
return readTextZipEntry(s, name);
}
}View on GitHub (pinned to 24702dc5a0)