Tencent/tinker · error · IllegalArgumentException
Name too long: {} UTF-8 bytes
Error message
Name too long: {} UTF-8 bytes What it means
Entry names are stored in zip headers with a 16-bit length field, so a name longer than 65,535 UTF-8 bytes cannot be encoded. putNextEntry encodes the name to UTF-8 and throws IllegalArgumentException (not ZipException) when the encoded length exceeds 0xffff. Note the limit is on bytes, not characters, so multi-byte characters reduce the character budget.
Source
Thrown at third-party/tinker-ziputils/src/main/java/com/tencent/tinker/ziputils/ziputil/AlignedZipOutputStream.java:336
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.)
flags |= GPBF_UTF8_FLAG;
writeLong(out, LOCSIG); // Entry header
writeShort(out, ZIPLocalHeaderVersionNeeded); // Extraction version
writeShort(out, flags);
writeShort(out, method);
View on GitHub (pinned to 1b7ea02c23)
Solutions
- Validate/limit entry name length (encoded UTF-8 bytes) at the point names are constructed; reject or truncate-and-slug long names.
- Flatten directory structure or shorten prefixes for generated entries (shorten the common root rather than each leaf).
- If genuinely long names are required, store them in a manifest entry inside the zip and use short placeholder entry names.
Example fix
// before: unbounded generated name
zos.putNextEntry(new ZipEntry(baseDir + "/" + repeatedSuffix(i))); // may exceed 64Ki bytes
// after: validate encoded length before creating the entry
String name = baseDir + "/" + repeatedSuffix(i);
if (name.getBytes(StandardCharsets.UTF_8).length > 0xffff) {
throw new IllegalArgumentException("entry name too long: " + name);
}
zos.putNextEntry(new ZipEntry(name)); Defensive patterns
Strategy: validation
Validate before calling
// Validate encoded name length before constructing the entry
static void checkEntryName(String name) {
int len = name.getBytes(java.nio.charset.StandardCharsets.UTF_8).length;
if (len > 0xffff) throw new IllegalArgumentException("entry name too long: " + len + " UTF-8 bytes");
} Try / catch
try {
zos.putNextEntry(new java.util.zip.ZipEntry(name));
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Name too long")) {
name = shorten(name); // truncate/slug and continue
zos.putNextEntry(new java.util.zip.ZipEntry(name));
} else {
throw e;
}
} Prevention
- Cap generated path depth and suffix length at construction time.
- Remember the limit is UTF-8 bytes, not characters, when names contain non-ASCII text.
- Fuzz-test name generators in builds that create names from unbounded input.
When it happens
Trigger: putNextEntry with a name whose UTF-8 encoding exceeds 65,535 bytes — deeply nested generated paths, hash-suffixed names, or a bug that concatenates path segments in a loop.
Common situations: Generated archives with unbounded name construction (e.g. appending suffixes per iteration); packaging user-supplied paths without length validation; encoding surprises where a name that fits in chars overflows in bytes due to CJK or emoji content.
Related errors
- Comment too long: {} bytes
- Expected ${DEX_IN_JAR_NAME} in ${file}
- CRC mismatch
- Size mismatch
- Entry already exists: {}
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/47137c2dc1ab5cbc.
Report an issue: GitHub.