GitoxideLabs/gitoxide · error
corrupt deflate stream
Error message
corrupt deflate stream: {cause} What it means
During inflation, the zlib decoder returned an error; the stream is corrupt. The underlying zlib error message is preserved in the message so callers can distinguish a checksum mismatch (`incorrect data check`) from genuine stream corruption. Returned as `InvalidInput` from `read()`.
Solutions
- Verify the input source integrity (re-fetch or restore the corrupted object/pack)
- Check that the complete compressed stream (including Adler-32 trailer) is being written to the inflater
- Compare the zlib message: 'incorrect data check' implies data corruption after decompression, other messages point at malformed deflate data
Example fix
// before
let mut buf = read_partial_file(path)?; // truncated
inflate.read_to_end(&mut out)?; // corrupt deflate stream
// after
let buf = std::fs::read(path).expect("complete compressed input");
assert!(!buf.is_empty());
inflate.read_to_end(&mut out)?; Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: confirm input is a complete zlib stream (checks 2-byte header)
fn looks_like_zlib(buf: &[u8]) -> bool {
buf.len() >= 2 && (buf[0] & 0x0f) == 8 && ((buf[0] as u16) << 8 | buf[1] as u16) % 31 == 0
} Try / catch
match inflate_stream.read_to_end(&mut out) {
Err(e) if e.kind() == std::io::ErrorKind::InvalidInput
&& e.to_string().contains("corrupt deflate stream") => {
if e.to_string().contains("incorrect data check") {
eprintln!("checksum mismatch: object data is corrupted; re-fetch");
} else {
eprintln!("malformed deflate data: {e}");
}
}
other => other?,
} Prevention
- Verify pack/object integrity with `git fsck` or gix fsck equivalents
- Write the entire compressed payload (including trailer) to the inflater before finishing
- Detect truncated writes upstream; do not feed partial buffers as complete streams
When it happens
Trigger: `gix_zlib::stream::inflate` `read()` encounters invalid deflate data, a truncated stream, or an Adler-32 checksum mismatch in the compressed input.
Common situations: Reading zlib-compressed data from a corrupted pack/loose object file; concatenating or truncating compressed blobs; feeding non-zlib data to an inflate stream.
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
- Should never see other errors than zlib, but got
- Should never see other errors than zlib, but got
- One or more errors occurred - checkout is incomplete
- could not inspect a reference before rebasing
- {err}
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/fb4d62cc7d1b0c72.
Report an issue: GitHub.
Appendix: source
Thrown at gix-zlib/src/stream/inflate.rs:43
dst = &mut dst[written..];
consumed = (state.total_in() - before_in) as usize;
}
rd.consume(consumed);
match ret {
// The stream has officially ended, nothing more to do here.
Ok(Status::StreamEnd) => return Ok(total_written),
// Either input our output are depleted even though the stream is not depleted yet.
Ok(Status::Ok | Status::BufError) if eof || dst.is_empty() => return Ok(total_written),
// Some progress was made in both the input and the output, it must continue to reach the end.
Ok(Status::Ok | Status::BufError) if consumed != 0 || written != 0 => continue,
// A strange state, where zlib makes no progress but isn't done either. Call it out.
Ok(Status::Ok | Status::BufError) => unreachable!("Definitely a bug somewhere"),
// Keep the underlying zlib error so callers can tell a checksum mismatch
// (`incorrect data check`) apart from genuine stream corruption.
Err(err) => {
let cause = state.error_message().map_or_else(|| err.to_string(), String::from);
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!("corrupt deflate stream: {cause}"),
));
}
}
}
}
View on GitHub (pinned to e73179060b)