quickwit-oss/tantivy · error · io::Error
InvalidData
InvalidData
Error message
GCD of 0 is forbidden
What it means
ColumnStats deserialization reads a GCD value that must be non-zero because it is wrapped in NonZeroU64 and multiplies the amplitude. A serialized gcd of 0 is invalid, so the reader returns InvalidData with this message. It signals corrupt or foreign-format stats data.
Source
Thrown at columnar/src/column_values/stats.rs:43
pub fn amplitude(&self) -> u64 {
self.max_value - self.min_value
}
}
impl BinarySerializable for ColumnStats {
fn serialize<W: Write + ?Sized>(&self, writer: &mut W) -> io::Result<()> {
VInt(self.min_value).serialize(writer)?;
VInt(self.gcd.get()).serialize(writer)?;
VInt(self.amplitude() / self.gcd).serialize(writer)?;
VInt(self.num_rows as u64).serialize(writer)?;
Ok(())
}
fn deserialize<R: io::Read>(reader: &mut R) -> io::Result<Self> {
let min_value = VInt::deserialize(reader)?.0;
let gcd = VInt::deserialize(reader)?.0;
let gcd = NonZeroU64::new(gcd)
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "GCD of 0 is forbidden"))?;
let amplitude = VInt::deserialize(reader)?.0 * gcd.get();
let max_value = min_value + amplitude;
let num_rows = VInt::deserialize(reader)?.0 as RowId;
Ok(ColumnStats {
min_value,
max_value,
num_rows,
gcd,
})
}
}
#[cfg(test)]
mod tests {
use std::num::NonZeroU64;
use common::BinarySerializable;
View on GitHub (pinned to b5d8deb80c)
Solutions
- Validate file integrity and re-index / re-export the column data.
- Confirm the byte stream is aligned — re-check where stats deserialization starts.
- Match reader and writer columnar format versions.
- Pre-check the gcd bytes in a custom reader and fail early with context.
Example fix
// before
let stats = ColumnStats::deserialize(&mut reader)?; // InvalidData on gcd==0
// after
if reader peeked gcd is 0 { /* treat as corrupt segment */ }
let stats = ColumnStats::deserialize(&mut reader)?; Defensive patterns
Strategy: try-catch
Try / catch
match ColumnStats::deserialize(&mut reader) {
Err(e) if e.kind() == std::io::ErrorKind::InvalidData
&& e.to_string().contains("GCD of 0") => {
// segment stats corrupted: rebuild or use fallback stats
}
other => other?,
} Prevention
- Verify segment integrity before deserializing stats.
- Keep reader/writer columnar format versions aligned.
- Re-check byte offsets feeding the stats stream to avoid misaligned reads.
- Rebuild indexes that were partially written by crashed processes.
When it happens
Trigger: Deserializing ColumnStats where the VInt read for gcd is 0 — e.g. from truncated/corrupted streams, zero-filled buffers, or data written by an incompatible encoder version.
Common situations: Reading column stats from damaged segment files; byte-offset misalignment causing a 0 to be read in the gcd slot; cross-version format mismatch.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
AI-assisted analysis of quickwit-oss/tantivy@b5d8deb80c (2026-09-05).
Data as JSON: /api/errors/f86fb7db64b9ca68.
Report an issue: GitHub.