Tencent/tinker · error · ZipException
Too many entries for the zip file format's 16-bit entry coun
Error message
Too many entries for the zip file format's 16-bit entry count
What it means
The zip format's central directory records the entry count in a 16-bit field, capping a classic zip at 65,535 entries. This stream does not implement Zip64, so once the running entries set reaches 64*1024-1 the next putNextEntry is refused. The check happens before any bytes are written for the new entry, keeping the archive consistent.
Source
Thrown at third-party/tinker-ziputils/src/main/java/com/tencent/tinker/ziputils/ziputil/AlignedZipOutputStream.java:331
}
if (ze.getCrc() == -1) {
throw new ZipException("STORED entry missing CRC");
}
if (ze.getSize() == -1) {
throw new ZipException("STORED entry missing size");
}
if (ze.getSize() != ze.getCompressedSize()) {
throw new ZipException("STORED entry size/compressed size mismatch");
}
}
checkOpen();
if (entries.contains(ze.getName())) {
throw new ZipException("Entry already exists: " + ze.getName());
}
if (entries.size() == 64*1024-1) {
throw new ZipException("Too many entries for the zip file format's 16-bit entry count");
}
nameBytes = ze.getName().getBytes(Charset.forName("UTF-8"));
nameLength = nameBytes.length;
if (nameLength > 0xffff) {
throw new IllegalArgumentException("Name too long: " + nameLength + " UTF-8 bytes");
}
def.setLevel(compressionLevel);
ze.setMethod(method);
currentEntry = ze;
entries.add(currentEntry.getName());
// Local file header.
// http://www.pkware.com/documents/casestudies/APPNOTE.TXT
int flags = (method == STORED) ? 0 : GPBF_DATA_DESCRIPTOR_FLAG;
// Java always outputs UTF-8 filenames. (Before Java 7, the RI didn't set this flag and used
// modified UTF-8. From Java 7, it sets this flag and uses normal UTF-8.)
View on GitHub (pinned to 1b7ea02c23)
Solutions
- Count entries before writing: if the planned set exceeds 65,535, prune redundant files (unused resources, duplicate metadata) until under the limit.
- Split the output into multiple archives (e.g. assets split, expansion files, multidex-style sharding) so each stays under 65,535 entries.
- If a single huge archive is a hard requirement, use a Zip64-capable writer for that artifact instead of this class, then verify consumers can read Zip64.
Example fix
// before: unconditional add in a loop
for (File f : files) {
zos.putNextEntry(new ZipEntry(prefix + f.getName())); // throws at 65535th
}
// after: pre-validate the entry budget
if (files.size() > 64 * 1024 - 1) {
throw new IllegalStateException("too many zip entries; split the archive");
}
for (File f : files) {
zos.putNextEntry(new ZipEntry(prefix + f.getName()));
} Defensive patterns
Strategy: validation
Validate before calling
// Check the entry budget up front
static final int MAX_ZIP_ENTRIES = 64 * 1024 - 1;
if (plannedEntryNames.size() > MAX_ZIP_ENTRIES) {
throw new IllegalStateException("archive would exceed the 65535-entry zip limit; split or prune");
} Try / catch
try {
zos.putNextEntry(entry);
} catch (java.util.zip.ZipException e) {
if (e.getMessage() != null && e.getMessage().contains("16-bit entry count")) {
// finish the current archive, roll over to a new part
zos.close();
zos = openNewPart();
zos.putNextEntry(entry);
} else {
throw e;
}
} Prevention
- Count planned entries before starting the archive.
- Prune duplicate/generated files early in the packaging pipeline.
- If huge single archives are expected, choose a Zip64-capable writer from the start.
When it happens
Trigger: Writing an archive with more than 65,535 entries — e.g. packaging a project with tens of thousands of resource/asset files, or accidentally adding generated/duplicated files in a loop until the limit is hit.
Common situations: Large apps whose res/ + assets/ + generated code push past 64K files; a build step that accidentally emits per-class or per-locale files without dedupe; using this non-Zip64 writer where the input archive is already near the limit (Android's AAPT-era limit is a known relative of this one).
Related errors
- Expected ${DEX_IN_JAR_NAME} in ${file}
- CRC mismatch
- Size mismatch
- Entry already exists: {}
- Name too long: {} UTF-8 bytes
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/6f2b362a57c2e564.
Report an issue: GitHub.