quickwit-oss/tantivy · error
Corrupted data. Invalid VInt 32
Error message
Corrupted data. Invalid VInt 32
What it means
VInt (variable-length integer) encoding terminates each byte with a stop bit. vint_len scans up to 5 bytes looking for the terminator; if none is found within 5 bytes the value cannot be a valid 32-bit vint, so the data is corrupt. This indicates deserialization from a truncated or corrupted buffer.
Source
Thrown at common/src/vint.rs:129
&buf[0..num_bytes]
}
/// Returns the number of bytes covered by a
/// serialized vint `u32`.
///
/// Expects a buffer data that starts
/// by the serialized `vint`, scans at most 5 bytes ahead until
/// it finds the vint final byte.
///
/// # May Panic
/// If the payload does not start by a valid `vint`
fn vint_len(data: &[u8]) -> usize {
for (i, &val) in data.iter().enumerate().take(5) {
if val >= STOP_BIT {
return i + 1;
}
}
panic!("Corrupted data. Invalid VInt 32");
}
/// Reads a vint `u32` from a buffer, and
/// consumes its payload data.
///
/// # Panics
///
/// If the buffer does not start by a valid
/// vint payload
pub fn read_u32_vint(data: &mut &[u8]) -> u32 {
let (result, vlen) = read_u32_vint_no_advance(data);
*data = &data[vlen..];
result
}
pub fn read_u32_vint_no_advance(data: &[u8]) -> (u32, usize) {
let vlen = vint_len(data);
let mut result = 0u32;View on GitHub (pinned to b5d8deb80c)
Solutions
- Validate and re-download / restore the corrupted segment files, or rebuild the index from source documents.
- Check that the reader's offset is correct — a prior field misparse can leave the cursor mid-vint; verify preceding read lengths.
- Confirm the file was written by a compatible tantivy version (vint format mismatches across versions).
Example fix
// before
let (val, len) = read_u32_vint_no_advance(data, offset)?; // panics on 5 continuation bytes
// after
if data.len() < offset + 5 {
return Err(corruption_error("truncated vint"));
}
let (val, len) = read_u32_vint_no_advance(data, offset)?; Defensive patterns
Strategy: fallback
Validate before calling
if data.len() < offset + 5 {
return Err(corruption());
} Try / catch
// panic is unrecoverable; isolate parsing
let result = std::panic::catch_unwind(|| read_vint(data, offset));
match result {
Ok(v) => v,
Err(_) => { mark_segment_corrupted(seg); skip_segment(seg) }
} Prevention
- Verify segment file integrity (checksums) before opening
- Re-download or rebuild corrupted segments
- Keep tantivy versions consistent between writer and reader
- Never resume parsing at an offset derived from a failed read
When it happens
Trigger: Calling read_u32_vint_no_advance (or any vint deserialization) on a byte slice where the first 5 bytes all have the continuation (stop) bit set — truncated input, misaligned buffer offset, or reading past the logical end of the vint payload.
Common situations: Corrupted/truncated index files (incomplete download, disk failure, partial write); reading at a wrong offset after a prior parsing bug; opening a segment written by a different/incompatible version; mixing files between index versions.
Related errors
AI-assisted analysis of quickwit-oss/tantivy@b5d8deb80c (2026-09-05).
Data as JSON: /api/errors/d6fed8cc49ef4a4a.
Report an issue: GitHub.