quickwit-oss/tantivy · error · io::Error

Invalid doc store version

Error message

Invalid doc store version {v}

What it means

Thrown during deserialization of DocStoreVersion when the u32 read from the file is neither 1 (V1) nor 2 (V2). The library only understands these doc store format versions; anything else means the file was written by an incompatible tantivy version or the bytes are misaligned/corrupt.

Solutions

  1. Read the index with the same (or newer, compatible) tantivy version that wrote it
  2. Rebuild the index with your current tantivy version if a downgrade is required
  3. Verify the segment file is intact and not corrupted/misaligned
  4. Check your index directory does not mix files from different tantivy versions

Example fix

// before
let version = DocStoreVersion::deserialize(&mut reader)?;
// after
let version = match DocStoreVersion::deserialize(&mut reader) {
    Ok(v) => v,
    Err(e) if e.kind() == io::ErrorKind::InvalidData => {
        eprintln!("incompatible doc store version, rebuilding index");
        return rebuild_index();
    }
    Err(e) => return Err(e),
};
Defensive patterns

Strategy: validation

Validate before calling

fn read_docstore_version(reader: &mut impl std::io::Read) -> std::io::Result<u32> {
    let mut buf = [0u8; 4];
    reader.read_exact(&mut buf)?;
    let v = u32::from_le_bytes(buf);
    if v != 1 && v != 2 {
        return Err(std::io::Error::new(
            std::io::ErrorKind::InvalidData,
            format!("unsupported doc store version {v}; this tantivy supports 1..=2"),
        ));
    }
    Ok(v)
}

Type guard

fn is_supported_docstore_version(v: u32) -> bool {
    matches!(v, 1 | 2)
}

Try / catch

match DocStoreVersion::deserialize(&mut reader) {
    Err(e) if e.kind() == std::io::ErrorKind::InvalidData
        && e.to_string().starts_with("Invalid doc store version") => {
        eprintln!("index written by incompatible tantivy; re-index required");
    }
    Err(e) => return Err(e.into()),
    Ok(v) => use_version(v),
}

Prevention

When it happens

Trigger: Opening an index written by a newer tantivy that uses a doc store version beyond V2; reading a corrupted or misaligned byte stream as the version field; pointing the reader at a non-doc-store file.

Common situations: Upgrading/downgrading tantivy across incompatible format versions; mixing segments written by different library versions in one directory; file corruption shifting the read offset.

Related errors


AI-assisted analysis of quickwit-oss/tantivy@b5d8deb80c (2026-09-05). Data as JSON: /api/errors/4ae4cd953346088d. Report an issue: GitHub.

Appendix: source

Thrown at src/store/reader.rs:53

impl Display for DocStoreVersion {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            DocStoreVersion::V1 => write!(f, "V1"),
            DocStoreVersion::V2 => write!(f, "V2"),
        }
    }
}
impl BinarySerializable for DocStoreVersion {
    fn serialize<W: io::Write + ?Sized>(&self, writer: &mut W) -> io::Result<()> {
        (*self as u32).serialize(writer)
    }

    fn deserialize<R: io::Read>(reader: &mut R) -> io::Result<Self> {
        Ok(match u32::deserialize(reader)? {
            1 => DocStoreVersion::V1,
            2 => DocStoreVersion::V2,
            v => {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidData,
                    format!("Invalid doc store version {v}"),
                ))
            }
        })
    }
}

/// Reads document off tantivy's [`Store`](./index.html)
pub struct StoreReader {
    decompressor: Decompressor,
    doc_store_version: DocStoreVersion,
    data: FileSlice,
    skip_index: Arc<SkipIndex>,
    space_usage: StoreSpaceUsage,
    cache: BlockCache,
}

View on GitHub (pinned to b5d8deb80c)