skylot/jadx · error · IOException

Zip file is too big

Error message

Zip file is too big

What it means

A hard size gate in JadxZipParser.load(). The custom parser memory-maps or fully buffers the archive into a single ByteBuffer, whose capacity is an int, so any file whose length is >= Integer.MAX_VALUE (~2 GiB) cannot be represented and is rejected before any mapping is attempted. This is an architectural limit of the custom parser, not the fallback parser.

Solutions

  1. If the file genuinely exceeds 2 GiB, the custom parser cannot handle it; split or shrink the archive (e.g., split per-ABI APKs, remove debug assets).
  2. Confirm the file is actually a zip and not a different large binary mislabeled.
  3. Use ZipReaderFlags.FALLBACK_AS_DEFAULT so jadx uses the streaming fallback parser which is not bound by the single-buffer int limit.
  4. Reduce the archive below the threshold by removing unused content.

Example fix

// before
ZipContent content = zipReader.open(largeFile); // custom parser throws

// after
ZipReader reader = new ZipReader(EnumSet.of(ZipReaderFlags.FALLBACK_AS_DEFAULT));
ZipContent content = reader.open(largeFile);
Defensive patterns

Strategy: validation

Validate before calling

// Reject files at/above the 2 GiB custom-parser limit before opening.
long MAX = (long) Integer.MAX_VALUE; // ~2 GiB
if (file.length() >= MAX) {
    throw new IOException("Zip too large for custom parser (>= 2 GiB): " + file.length());
}

Try / catch

try {
    content = zipReader.open(file);
} catch (IOException e) {
    if (e.getMessage().contains("too big")) {
        // switch to streaming fallback parser which is not int-capacity bound
        reader = new ZipReader(EnumSet.of(ZipReaderFlags.FALLBACK_AS_DEFAULT));
        content = reader.open(file);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Opening an archive whose RandomAccessFile.length() reports >= 2^31-1 bytes through the custom JadxZipParser. Files < 100 MiB are read into a heap byte[]; larger ones are memory-mapped, but both paths are gated by the same int-capacity check.

Common situations: Very large APKs, AABs, or supersets/zipped SDKs that exceed 2 GiB; a misidentified file (e.g., a disk image with a .zip extension); archives that grew past the limit after bundling many ABIs/assets.

Related errors


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

Appendix: source

Thrown at jadx-commons/jadx-zip/src/main/java/jadx/zip/parser/JadxZipParser.java:138

	}

	private ByteBuffer getBuffer() {
		ByteBuffer buf = byteBuffer;
		if (buf == null) {
			throw new RuntimeException("File not opened: " + zipFile);
		}
		return buf;
	}

	private void load() throws IOException {
		if (byteBuffer != null) {
			// already loaded
			return;
		}
		RandomAccessFile raFile = new RandomAccessFile(zipFile, "r");
		long size = raFile.length();
		if (size >= Integer.MAX_VALUE) {
			throw new IOException("Zip file is too big");
		}
		int fileLen = (int) size;
		if (fileLen < 100 * 1024 * 1024) {
			// load files smaller than 100MB directly into memory
			byte[] bytes = new byte[fileLen];
			raFile.readFully(bytes);
			byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
			raFile.close();
		} else {
			// for big files - use a memory mapped file
			file = raFile;
			fileChannel = raFile.getChannel();
			byteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
			byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
		}
	}

	private List<IZipEntry> searchLocalFileHeaders(int maxEntriesCount) {

View on GitHub (pinned to e738a26571)