skylot/jadx · error · DataFormatException
Unexpected size of decompressed entry: ${entry}, got: ${writ
Error message
Unexpected size of decompressed entry: ${entry}, got: ${written}, expected: ${out.length} What it means
A data-integrity check in ZipDeflate. After inflating an entry's compressed payload into a buffer sized to the declared uncompressed size, jadx compares the number of bytes actually produced (inflater.inflate return value) against out.length (the declared size). A mismatch means the entry's size header is wrong or the data is corrupt, and a DataFormatException is thrown with got/expected counts. This guards against silent partial output.
Source
Thrown at jadx-commons/jadx-zip/src/main/java/jadx/zip/parser/ZipDeflate.java:27
import static jadx.zip.parser.JadxZipParser.bufferToStream;
final class ZipDeflate {
private static final int BUFFER_SIZE = 4096;
static byte[] decompressEntryToBytes(ByteBuffer buf, JadxZipEntry entry) throws DataFormatException {
buf.position(entry.getDataStart());
ByteBuffer entryBuf = buf.slice();
entryBuf.limit((int) entry.getCompressedSize());
if (entry.getUncompressedSize() > Integer.MAX_VALUE) {
throw new DataFormatException("Entry too large: " + entry.getUncompressedSize());
}
byte[] out = new byte[(int) entry.getUncompressedSize()];
Inflater inflater = new Inflater(true);
inflater.setInput(entryBuf);
int written = inflater.inflate(out);
inflater.end();
if (written != out.length) {
throw new DataFormatException("Unexpected size of decompressed entry: " + entry
+ ", got: " + written + ", expected: " + out.length);
}
return out;
}
static InputStream decompressEntryToStream(ByteBuffer buf, JadxZipEntry entry) {
InputStream stream = bufferToStream(buf, entry.getDataStart(), (int) entry.getCompressedSize());
Inflater inflater = new Inflater(true);
return new InflaterInputStream(stream, inflater, BUFFER_SIZE);
}
}
View on GitHub (pinned to e738a26571)
Solutions
- Inspect the got vs expected counts: a large gap usually means truncation; a small gap often means a bad size header.
- Re-acquire the archive from a trusted source.
- Allow jadx to fall back per-entry (do not set DONT_USE_FALLBACK) so the fallback parser can retry.
- If repackaging, ensure the uncompressed-size field matches the real decompressed length.
Defensive patterns
Strategy: try-catch
Validate before calling
// You cannot fully pre-validate without decompressing, but you can reject
// entries whose declared uncompressed size is implausible.
long uncomp = entry.getUncompressedSize();
if (uncomp < 0 || uncomp > MAX_ENTRY) {
throw new IOException("Implausible uncompressed size for " + entry.getName());
} Try / catch
try {
byte[] out = ZipDeflate.decompressEntry(buf, entry);
} catch (java.util.zip.DataFormatException e) {
if (e.getMessage().contains("Unexpected size")) {
LOG.warn("Size mismatch for entry {}, skipping", entry);
continue;
}
throw e;
} Prevention
- Treat a got/expected size mismatch as corruption; re-acquire the archive.
- Keep the fallback enabled so per-entry failures can retry.
- When repackaging, ensure uncompressed-size fields are accurate.
When it happens
Trigger: Decompressing a DEFLATE entry (compressMethod == 8) via ZipDeflate where Inflater.inflate() returns fewer bytes than entry.getUncompressedSize() (it never returns more because the output buffer is exactly that size). Reached during custom-parser entry reads and batch decompression.
Common situations: A tampered or truncated entry whose compressed data is shorter than declared; an obfuscator that lies about uncompressed size to confuse tools; a partially downloaded archive; a zip rebuilt incorrectly by merging tools.
Related errors
- Failed to read bytes for entry: {}
- Failed to open input stream for entry: {}
- Failed to open zip: {}, error: {}
- Entry is encrypted, failed to decompress: {}
- Failed to decompress zip entry: {}, error: {}
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/83a8d059e472c91b.
Report an issue: GitHub.