Tencent/tinker · info · IOException
Size mismatch on inflated file: ${bytesRead} vs ${entry.size
Error message
Size mismatch on inflated file: ${bytesRead} vs ${entry.size} What it means
IOException('Size mismatch on inflated file: <bytesRead> vs <entry.size>') also lives inside the commented-out ZipInflaterInputStream class (TinkerZipFile.java:569 onward) and is unreachable in this fork. Its original purpose: when the inflater reports EOF, compare the number of bytes actually inflated (bytesRead) with the uncompressed size recorded in the entry's metadata (entry.size); a mismatch means either the deflate stream or the size field is wrong. In the live code of this repository it can never be thrown.
Source
Thrown at third-party/tinker-ziputils/src/main/java/com/tencent/tinker/ziputils/ziputil/TinkerZipFile.java:586
/** @hide */
/*public static class ZipInflaterInputStream extends InflaterInputStream {
private final ZipEntry entry;
private long bytesRead = 0;
public ZipInflaterInputStream(InputStream is, Inflater inf, int bsize, ZipEntry entry) {
super(is, inf, bsize);
this.entry = entry;
}
@Override public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
final int i;
try {
i = super.read(buffer, byteOffset, byteCount);
} catch (IOException e) {
throw new IOException("Error reading data for " + entry.getName() + " near offset "
+ bytesRead, e);
}
if (i == -1) {
if (entry.size != bytesRead) {
throw new IOException("Size mismatch on inflated file: " + bytesRead + " vs "
+ entry.size);
}
} else {
bytesRead += i;
}
return i;
}
@Override public int available() throws IOException {
if (closed) {
// Our superclass will throw an exception, but there's a jtreg test that
// explicitly checks that the InputStream returned from ZipFile.getInputStream
// returns 0 even when closed.
return 0;
}
return super.available() == 0 ? 0 : (int) (entry.getSize() - bytesRead);
}
}*/
}View on GitHub (pinned to 1b7ea02c23)
Solutions
- If hit on an AOSP-derived build: verify whether the deflate stream or the size field is wrong (inflate fully with an independent tool); usually the archive must be regenerated.
- Ensure any tool that rewrites entry contents also updates size/crc in the central directory and local headers.
- In this repository, no handling needed — dead code.
Defensive patterns
Strategy: try-catch
Try / catch
// only relevant on builds where ZipInflaterInputStream is enabled (not this fork)
try {
readFully(in, expectedSize);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Size mismatch on inflated file")) {
// metadata disagrees with actual inflated bytes — archive is inconsistent
throw new IOException("Entry size metadata does not match data; rebuild archive", e);
}
throw e;
} Prevention
- Any tool that rewrites entry data must also update size and CRC in both headers and the CD.
- Verify size fields against actual inflated output when generating archives.
- In this fork, no handling needed — dead code.
When it happens
Trigger: In builds where the class is active: reading an entry whose DEFLATE stream ends at a different byte count than the central directory's uncompressed-size field — truncated data, an entry recompressed without updating sizes, or a tampered size field. In this repository: unreachable.
Common situations: Hot-patch/zip-flushing tools that rewrite entry data but keep stale size metadata; partially downloaded archives; auditing logs from a build derived from AOSP's zip implementation.
Related errors
- Error reading data for ${entry.getName()} near offset ${byte
- STORED entry size/compressed size mismatch
- Expected ${DEX_IN_JAR_NAME} in ${file}
- CRC mismatch
- Size mismatch
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/3bc68e68f6fd9312.
Report an issue: GitHub.