skylot/jadx · error · RuntimeException

Failed to open zip file: ${file.getAbsolutePath()}

Error message

Failed to open zip file: ${file.getAbsolutePath()}

What it means

Thrown by ResourcesLoader.defaultLoadFile() when opening an input file that FileUtils.isZipFile() identified as a zip, but decompiler.getZipReader().open(file) then throws. jadx registers the ZipContent as a closeable and enumerates its entries; if open fails it wraps the cause in a RuntimeException naming the absolute path. This is part of resource discovery (loading the list of ResourceFiles from input files), not entry-level decoding.

Source

Thrown at jadx-core/src/main/java/jadx/api/ResourcesLoader.java:211

				return;
			}
		}

		// If no custom decoder was able to decode the resources, use the default decoder
		defaultLoadFile(list, file, "");
	}

	public void defaultLoadFile(List<ResourceFile> list, File file, String subDir) {
		if (FileUtils.isZipFile(file)) {
			try {
				ZipContent zipContent = decompiler.getZipReader().open(file);
				// do not close a zip now, entry content will be read later
				decompiler.addCloseable(zipContent);
				for (IZipEntry entry : zipContent.getEntries()) {
					addEntry(list, file, entry, subDir);
				}
			} catch (Exception e) {
				throw new RuntimeException("Failed to open zip file: " + file.getAbsolutePath(), e);
			}
		} else {
			ResourceType type = ResourceType.getFileType(file.getAbsolutePath());
			list.add(ResourceFile.createResourceFile(decompiler, file, type));
		}
	}

	public void addEntry(List<ResourceFile> list, File zipFile, IZipEntry entry, String subDir) {
		if (entry.isDirectory()) {
			return;
		}
		String name = entry.getName();
		ResourceType type = ResourceType.getFileType(name);
		ResourceFile rf = ResourceFile.createResourceFile(decompiler, subDir + name, type);
		if (rf != null) {
			rf.setZipEntry(entry);
			list.add(rf);
		}

View on GitHub (pinned to e738a26571)

Solutions

  1. Inspect getCause() to see the underlying open failure (IO, size-limit, structure).
  2. Verify the file is a complete, valid zip before adding it to the input list.
  3. Ensure no other process holds an exclusive lock on the file.
  4. If the file is not meant to be treated as a zip, exclude it from the input set or rename it.

Example fix

// before
resLoader.defaultLoadFile(list, inputFile, "");

// after
if (FileUtils.isZipFile(inputFile)) {
    try {
        resLoader.defaultLoadFile(list, inputFile, "");
    } catch (RuntimeException e) {
        LOG.warn("Failed to open resource zip {}, skipping: {}", inputFile.getAbsolutePath(), e.getCause());
    }
} else {
    LOG.warn("Input {} is not a zip, skipping", inputFile.getAbsolutePath());
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-validate the file is a real, openable zip before resource loading.
if (FileUtils.isZipFile(file)) {
    try (java.util.zip.ZipFile zf = new java.util.zip.ZipFile(file)) {
        // ok
    } catch (IOException e) {
        LOG.warn("Skipping unreadable zip {}: {}", file, e.getMessage());
        return;
    }
}

Try / catch

try {
    resLoader.defaultLoadFile(list, file, subDir);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("Failed to open zip file")) {
        LOG.warn("Skipping resource zip {}: {}", file, e.getCause());
    } else throw e;
}

Prevention

When it happens

Trigger: Calling resource loading on an input set containing a file that passes isZipFile() (has zip magic) but cannot be opened by the ZipReader (truncated, corrupt central directory, locked, or a false-positive zip signature).

Common situations: An APK/AAB/JAR in the input list that is truncated or corrupt; a file that happens to start with 'PK' but is not a real zip; a file exclusively locked by another process; a partially downloaded archive; a large zip that exceeds parser limits during resource scanning.

Related errors


AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14). Data as JSON: /api/errors/4cfef91eb56b497d. Report an issue: GitHub.