HMCL-dev/HMCL · error
Zip entry has an invalid symlink target:
Error message
Zip entry has an invalid symlink target:
What it means
When an archive entry is a symbolic link, Unzipper parses its target string with Path.of; if the target is not a valid path (invalid characters, null bytes, empty), the InvalidPathException is wrapped in an IOException naming the entry.
Solutions
- Remove or fix the invalid symlink entries in the archive before distribution
- Skip symlink entries when extracting on platforms that cannot represent them
- Repackage the archive with relative, portable link targets
- Re-download the archive in case of corruption
Example fix
// before // archive entry: link -> 'C:\bad:target' (illegal on Windows) // after // repackage with: ln -s ../../lib/shared.so link
Defensive patterns
Strategy: validation
Validate before calling
// pre-scan symlink entries
try (ZipFile zf = new ZipFile(zip)) {
for (ZipEntry e : Collections.list(zf.entries())) {
if (isSymlinkEntry(e)) {
String target = readLinkTarget(zf, e);
try { Path.of(target); } catch (InvalidPathException ex) {
throw new IOException("invalid symlink target: " + e.getName());
}
}
}
} Try / catch
try {
unzipper.unzip();
} catch (IOException e) {
if (e.getMessage().startsWith("Zip entry has an invalid symlink target")) {
// skip or repack the archive without symlinks
} else throw e;
} Prevention
- Package archives without platform-specific symlinks when possible
- Use relative, portable link targets
- Validate archives from Unix build machines before Windows distribution
- Re-download corrupted archives instead of hand-editing
When it happens
Trigger: Extracting archives whose symlink entries contain targets with illegal path characters (e.g. NUL bytes, reserved Windows characters like ':' or '?'), or malformed/empty link targets.
Common situations: Unix-authored archives containing symlinks with unusual targets extracted on Windows; archives corrupted or hand-edited; packaging tools emitting non-portable symlink entries.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Theme pack does not contain
- Not a valid world zip file since level.dat or…
- Cannot find suitable encoding for the zip.
- Not a zip file
- Zip entry is trying to write outside of the destination…
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/adb68a5d263dab2b.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/Unzipper.java:129
continue;
}
entryCount++;
if (entry.isDirectory()) {
Files.createDirectories(destFile);
} else {
Files.createDirectories(destFile.getParent());
if (entry.isUnixSymlink()) {
String linkTarget = reader.getUnixSymlink(entry);
if (replaceExistentFile)
Files.deleteIfExists(destFile);
Path targetPath;
try {
targetPath = Path.of(linkTarget);
} catch (InvalidPathException e) {
throw new IOException("Zip entry has an invalid symlink target: " + entry.getName(), e);
}
if (!destFile.getParent().resolve(targetPath).toAbsolutePath().normalize().startsWith(destDir)) {
throw new IOException("Zip entry is trying to create a symlink outside of the destination directory: " + entry.getName());
}
try {
Files.createSymbolicLink(destFile, targetPath);
} catch (FileAlreadyExistsException ignored) {
}
} else {
try (InputStream input = reader.getInputStream(entry)) {
Files.copy(input, destFile, copyOptions);
} catch (FileAlreadyExistsException e) {
if (replaceExistentFile)
throw e;
}
View on GitHub (pinned to 24702dc5a0)