MuntashirAkon/AppManager · error · IOException
Gzip-compressed data is corrupt
Error message
Gzip-compressed data is corrupt
What it means
read() feeds data through java.util.zip.Inflater; when inflate() raises DataFormatException, the deflate stream is malformed and the library rethrows it as IOException("Gzip-compressed data is corrupt"). This is the generic mid-stream corruption/invalid-deflate-data error.
Solutions
- Re-acquire the file and verify a checksum (e.g. md5sum against the source) to confirm corruption.
- Check whether the stream is truncated — if the transfer can be retried/range-resumed, redo it.
- Wrap reads in try-catch for IOException to fail gracefully and surface the corrupt-input condition to the operator.
Example fix
// before
InputStream gz = new GzipCompressorInputStream(in);
IOUtils.copy(gz, out);
// after
try (InputStream gz = new GzipCompressorInputStream(in)) {
IOUtils.copy(gz, out);
} catch (IOException e) {
if (e.getMessage().contains("corrupt")) {
throw new IOException("Source file damaged; re-fetch and verify checksum", 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("Gzip-compressed data is corrupt")) {
// input corrupted mid-stream: retry from a verified source, do not retry blindly
throw new IOException("corrupt gzip payload; re-fetch source", e);
}
throw e;
} Prevention
- Verify checksums (md5/sha256) of downloads before decompression.
- Ensure transfers are binary-safe (no text-mode/CRLF translation).
- Detect truncation: compare file size or use range-verified downloads.
When it happens
Trigger: Truncated or bit-corrupted deflate blocks; decoding a file that is not actually deflate-compressed after a valid-looking header; stream read offset desynchronization (e.g. skipped header bytes incorrectly).
Common situations: Incomplete downloads/interrupted transfers; decoding multi-part files joined incorrectly; storage media corruption; parsing a .gz whose header parsed but body was replaced.
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 (CRC32 error)
- Gzip-compressed data is corrupt (uncompressed size mismatch)
- 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/e6cd7b6595629e59.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorInputStream.java:297
while (len > 0) {
if (inf.needsInput()) {
// Remember the current position because we may need to
// rewind after reading too much input.
in.mark(buf.length);
bufUsed = in.read(buf);
if (bufUsed == -1) {
throw new EOFException();
}
inf.setInput(buf, 0, bufUsed);
}
final int ret;
try {
ret = inf.inflate(b, off, len);
} catch (final DataFormatException e) { // NOSONAR
throw new IOException("Gzip-compressed data is corrupt");
}
crc.update(b, off, ret);
off += ret;
len -= ret;
size += ret;
count(ret);
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();
}
View on GitHub (pinned to 0152f468fc)