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

  1. Remove or fix the invalid symlink entries in the archive before distribution
  2. Skip symlink entries when extracting on platforms that cannot represent them
  3. Repackage the archive with relative, portable link targets
  4. 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

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


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)