{"record":{"id":"ea7a5b9b357960fc","repo":"quickwit-oss/tantivy","slug":"unexpectedeof","errorCode":"UnexpectedEof","errorMessage":"Failed to deserialize column index. Empty buffer.","messagePattern":"Failed to deserialize column index\\. Empty buffer\\.","errorType":"error_code","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"columnar/src/column_index/serialize.rs","lineNumber":72,"sourceCode":"        SerializableColumnIndex::Optional(SerializableOptionalIndex {\n            non_null_row_ids,\n            num_rows,\n        }) => serialize_optional_index(non_null_row_ids.as_ref(), num_rows, &mut output)?,\n        SerializableColumnIndex::Multivalued(multivalued_index) => {\n            serialize_multivalued_index(&multivalued_index, &mut output)?\n        }\n    }\n    let column_index_num_bytes = output.written_bytes() as u32;\n    Ok(column_index_num_bytes)\n}\n\n/// Open a serialized column index.\npub fn open_column_index(\n    mut bytes: OwnedBytes,\n    format_version: Version,\n) -> io::Result<ColumnIndex> {\n    if bytes.is_empty() {\n        return Err(io::Error::new(\n            io::ErrorKind::UnexpectedEof,\n            \"Failed to deserialize column index. Empty buffer.\",\n        ));\n    }\n    let cardinality_code = bytes[0];\n    let cardinality = Cardinality::try_from_code(cardinality_code)?;\n    bytes.advance(1);\n    match cardinality {\n        Cardinality::Full => Ok(ColumnIndex::Full),\n        Cardinality::Optional => {\n            let optional_index = super::optional_index::open_optional_index(bytes)?;\n            Ok(ColumnIndex::Optional(optional_index))\n        }\n        Cardinality::Multivalued => {\n            let multivalue_index =\n                super::multivalued_index::open_multivalued_index(bytes, format_version)?;\n            Ok(ColumnIndex::Multivalued(multivalue_index))\n        }","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/quickwit-oss/tantivy/blob/b5d8deb80c26924e6b007a5b1a7630f35ca64de4/columnar/src/column_index/serialize.rs#L54-L90","documentation":"open_column_index deserializes a serialized column index; the first byte encodes the cardinality. An empty buffer cannot even supply that byte, so the function returns UnexpectedEof with this message. It typically means truncated or missing columnar data.","triggerScenarios":"Passing an empty OwnedBytes to open_column_index — e.g. reading a zero-length column-index region from a truncated segment, a failed mmap, or wrong offset/length when loading columnar files.","commonSituations":"Incomplete segment writes (crash during commit), corrupted downloads/copies of index directories, misaligned byte-range reads, opening columns that were never written.","solutions":["Check that the segment file is complete and not truncated; re-copy or re-index.","Verify offsets/lengths used to slice the column index bytes come from the correct footer/meta.","Handle empty buffers before calling: treat as missing column and fall back to a non-indexed access path.","Rebuild the index if corruption is confirmed."],"exampleFix":"// before\nlet idx = open_column_index(bytes, version)?; // UnexpectedEof if empty\n// after\nif bytes.is_empty() {\n    return Ok(ColumnIndex::empty()); // or skip column\n}\nlet idx = open_column_index(bytes, version)?;","handlingStrategy":"validation","validationCode":"fn open_column_index_safe(bytes: OwnedBytes, version: Version) -> io::Result<Option<ColumnIndex>> {\n    if bytes.is_empty() {\n        return Ok(None); // column index absent\n    }\n    open_column_index(bytes, version).map(Some)\n}","typeGuard":null,"tryCatchPattern":"match open_column_index(bytes, version) {\n    Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => {\n        // fall back to unindexed column access or rebuild segment\n    }\n    other => other.map(Some),\n}","preventionTips":["Ensure commits complete before reading segments (check for crash-incomplete segments).","Validate file sizes against the segment meta/footer before slicing byte ranges.","Handle empty/missing column regions explicitly instead of passing empty buffers.","Re-download or re-index damaged index directories."],"tags":["io","deserialization","eof","corruption"],"backgroundTag":"truncated-column-index","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"}