{"record":{"id":"d6fed8cc49ef4a4a","repo":"quickwit-oss/tantivy","slug":"corrupted-data-invalid-vint-32","errorCode":null,"errorMessage":"Corrupted data. Invalid VInt 32","messagePattern":"Corrupted data\\. Invalid VInt 32","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/src/vint.rs","lineNumber":129,"sourceCode":"    &buf[0..num_bytes]\n}\n\n/// Returns the number of bytes covered by a\n/// serialized vint `u32`.\n///\n/// Expects a buffer data that starts\n/// by the serialized `vint`, scans at most 5 bytes ahead until\n/// it finds the vint final byte.\n///\n/// # May Panic\n/// If the payload does not start by a valid `vint`\nfn vint_len(data: &[u8]) -> usize {\n    for (i, &val) in data.iter().enumerate().take(5) {\n        if val >= STOP_BIT {\n            return i + 1;\n        }\n    }\n    panic!(\"Corrupted data. Invalid VInt 32\");\n}\n\n/// Reads a vint `u32` from a buffer, and\n/// consumes its payload data.\n///\n/// # Panics\n///\n/// If the buffer does not start by a valid\n/// vint payload\npub fn read_u32_vint(data: &mut &[u8]) -> u32 {\n    let (result, vlen) = read_u32_vint_no_advance(data);\n    *data = &data[vlen..];\n    result\n}\n\npub fn read_u32_vint_no_advance(data: &[u8]) -> (u32, usize) {\n    let vlen = vint_len(data);\n    let mut result = 0u32;","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/quickwit-oss/tantivy/blob/b5d8deb80c26924e6b007a5b1a7630f35ca64de4/common/src/vint.rs#L111-L147","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nlet (val, len) = read_u32_vint_no_advance(data, offset)?; // panics on 5 continuation bytes\n// after\nif data.len() < offset + 5 {\n    return Err(corruption_error(\"truncated vint\"));\n}\nlet (val, len) = read_u32_vint_no_advance(data, offset)?;","handlingStrategy":"fallback","validationCode":"if data.len() < offset + 5 {\n    return Err(corruption());\n}","typeGuard":null,"tryCatchPattern":"// panic is unrecoverable; isolate parsing\nlet result = std::panic::catch_unwind(|| read_vint(data, offset));\nmatch result {\n    Ok(v) => v,\n    Err(_) => { mark_segment_corrupted(seg); skip_segment(seg) }\n}","preventionTips":["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"],"tags":["panic","vint","deserialization","corruption","io"],"backgroundTag":"corrupted-index-data","analyzedSha":"b5d8deb80c26924e6b007a5b1a7630f35ca64de4","analyzedAt":"2026-09-05T13:20:51.521Z","contentChangedAt":"2026-09-05T13:20:51.521Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}