MuntashirAkon/AppManager · error · IOException
Gzip-compressed data is corrupt (CRC32 error)
Error message
Gzip-compressed data is corrupt (CRC32 error)
What it means
Each .gz member ends with a CRC32 of the uncompressed data. read() compares the stored CRC32 with the computed one and throws IOException("Gzip-compressed data is corrupt (CRC32 error)") on mismatch. The deflate stream decoded fine, but the recovered bytes differ from what the compressor recorded.
Solutions
- Re-download/re-extract the file and compare checksums at the transport layer.
- Check the pipeline for byte-altering steps (encoding conversions, CRLF translation) and switch to binary-safe transfers.
- Restore from a known-good backup if the storage medium is suspect.
Example fix
// before
// blindly decode
IOUtils.copy(gz, out);
// after
try {
IOUtils.copy(gz, out);
} catch (IOException e) {
if (e.getMessage().contains("CRC32")) {
// verify source integrity and re-transfer
throw new IOException("Corrupt gzip member; re-fetch source", e);
}
throw e;
} Defensive patterns
Strategy: try-catch
Try / catch
try (InputStream gz = new GzipCompressorInputStream(rawIn)) {
IOUtils.copy(gz, out);
} catch (IOException e) {
if (e.getMessage().contains("CRC32 error")) {
// decoded bytes do not match the recorded digest — data integrity failure
throw new IOException("gzip integrity check failed; restore from verified copy", e);
}
throw e;
} Prevention
- Verify source checksums before decompressing.
- Avoid post-compression edits to archived files; recompress after any change.
- Keep binary-safe transfer channels end-to-end.
When it happens
Trigger: Bit corruption in compressed or decompressed bytes; an implementation bug producing different bytes; tampered/patched file content while keeping the original trailer.
Common situations: Silent disk/network corruption; files edited after compression; faulty pipelines that alter bytes in transit (e.g. text-mode transformations).
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- Gzip-compressed data is corrupt (uncompressed size mismatch)
- Gzip-compressed data is corrupt
- Unsupported compression method " + method + " in the .gz…
- Bad block header
- BZip2 block size is invalid
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/34e6af7bdb6c3c04.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorInputStream.java:324
if (inf.finished()) {
// We may have read too many bytes. Rewind the read
// position to match the actual amount used.
in.reset();
final int skipAmount = bufUsed - inf.getRemaining();
if (IOUtils.skip(in, skipAmount) != skipAmount) {
throw new IOException();
}
bufUsed = 0;
final DataInput inData = new DataInputStream(in);
// CRC32
final long crcStored = ByteUtils.fromLittleEndian(inData, 4);
if (crcStored != crc.getValue()) {
throw new IOException("Gzip-compressed data is corrupt (CRC32 error)");
}
// Uncompressed size modulo 2^32 (ISIZE in the spec)
final long isize = ByteUtils.fromLittleEndian(inData, 4);
if (isize != (inf.getBytesWritten() & 0xffffffffL)) {
throw new IOException("Gzip-compressed data is corrupt (uncompressed size mismatch)");
}
// See if this is the end of the file.
if (!decompressConcatenated || !init(false)) {
inf.end();
inf = null;
endReached = true;
return size == 0 ? -1 : size;
}
}
}View on GitHub (pinned to 0152f468fc)