grpc/grpc-java · error · ZipException
Corrupt GZIP trailer
Error message
Corrupt GZIP trailer
What it means
Each gzip member ends with an 8-byte trailer: CRC32 of the uncompressed data and ISIZE (uncompressed size mod 2^32). processTrailer compares both against the values tracked while inflating; any mismatch throws ZipException('Corrupt GZIP trailer'), meaning the decompressed bytes do not match what the compressor committed to.
Source
Thrown at core/src/main/java/io/grpc/internal/GzipInflatingBuffer.java:468
gzippedData.readBytes(inflaterInput, inflaterInputStart, bytesToAdd);
inflater.setInput(inflaterInput, inflaterInputStart, bytesToAdd);
state = State.INFLATING;
return true;
}
private boolean processTrailer() throws ZipException {
if (inflater != null
&& gzipMetadataReader.readableBytes() <= GZIP_HEADER_MIN_SIZE + GZIP_TRAILER_SIZE) {
// We don't have enough bytes to begin inflating a concatenated gzip stream, drop context
inflater.end();
inflater = null;
}
if (gzipMetadataReader.readableBytes() < GZIP_TRAILER_SIZE) {
return false;
}
if (crc.getValue() != gzipMetadataReader.readUnsignedInt()
|| expectedGzipTrailerIsize != gzipMetadataReader.readUnsignedInt()) {
throw new ZipException("Corrupt GZIP trailer");
}
crc.reset();
state = State.HEADER;
return true;
}
}
View on GitHub (pinned to 64daddc1f3)
Solutions
- Run `gzip -t` on a captured payload to confirm trailer corruption occurs upstream
- Bypass or fix body-rewriting intermediaries (recompressing proxies, CDN caches)
- Retry the RPC — single-bit corruption is often transient; persistent failure points at the sender
- Add TLS if the traffic path is unencrypted, since TLS integrity checks catch such corruption
Defensive patterns
Strategy: retry
Validate before calling
// pre-validate payload with an independent gzip decoder:
try (GZIPInputStream in = new GZIPInputStream(new ByteArrayInputStream(payload))) { in.readAllBytes(); } Try / catch
try { call(...); } catch (StatusRuntimeException e) {
if (e.getCause() instanceof ZipException && e.getCause().getMessage().contains("Corrupt GZIP trailer")) {
// discard response and retry once; escalate if it recurs
} else throw e;
} Prevention
- Enable TLS to detect corruption in transit
- Avoid caches/proxies that re-encode bodies without recomputing gzip trailers
- Retry once on transient corruption; persistent failures indicate sender-side breakage
When it happens
Trigger: After finishing a gzip member, the CRC32 of all inflated output differs from the trailer's CRC field, or the byte count differs from ISIZE — bit corruption, truncation, or body rewriting anywhere between compression and decompression.
Common situations: Flaky network or NIC corruption; proxies/caches that re-encode bodies and forget to recompute the trailer; storage corruption of cached responses; concurrent writes to the compressed blob.
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
- Corrupt GZIP header
- Unsupported compression method
- Inflater data format exception:
- Not in GZIP format
- No ALTS context information found
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/af2ea853eaf851d4.
Report an issue: GitHub.