quickwit-oss/tantivy · error · io::Error
UnexpectedEof
UnexpectedEof
Error message
File corrupted. The file is smaller than 4 bytes (len={}). What it means
Every tantivy segment file ends with a footer whose minimum size is 4 bytes (the footer magic number plus metadata). extract_footer rejects any file smaller than 4 bytes because it cannot possibly contain a valid footer, so the file is treated as corrupted from the start.
Source
Thrown at src/directory/footer.rs:56
Footer { version, crc }
}
pub(crate) fn crc(&self) -> CrcHashU32 {
self.crc
}
pub(crate) fn append_footer<W: io::Write>(&self, mut write: &mut W) -> io::Result<()> {
let mut counting_write = CountingWriter::wrap(&mut write);
counting_write.write_all(serde_json::to_string(&self)?.as_ref())?;
let footer_payload_len = counting_write.written_bytes();
BinarySerializable::serialize(&(footer_payload_len as u32), write)?;
BinarySerializable::serialize(&FOOTER_MAGIC_NUMBER, write)?;
Ok(())
}
/// Extracts the tantivy Footer from the file and returns the footer and the rest of the file
pub fn extract_footer(file: FileSlice) -> io::Result<(Footer, FileSlice)> {
if file.len() < 4 {
return Err(io::Error::new(
io::ErrorKind::UnexpectedEof,
format!(
"File corrupted. The file is smaller than 4 bytes (len={}).",
file.len()
),
));
}
let footer_metadata_len = <(u32, u32)>::SIZE_IN_BYTES;
let (footer_len, footer_magic_byte): (u32, u32) = file
.slice_from_end(footer_metadata_len)
.read_bytes()?
.as_ref()
.deserialize()?;
if footer_magic_byte != FOOTER_MAGIC_NUMBER {
return Err(io::Error::new(
io::ErrorKind::InvalidData,View on GitHub (pinned to b5d8deb80c)
Solutions
- Delete or restore the undersized file; it cannot contain valid data
- Rebuild the index or restore it from a backup
- Check for disk-full or interrupted-write issues on the source filesystem
- Compare the directory against commit metadata (meta.json) to identify missing/corrupt segments
Defensive patterns
Strategy: validation
Validate before calling
let md = std::fs::metadata(path)?;
if md.len() < 4 { /* skip / quarantine / restore this file */ } Try / catch
match extract_footer(file_slice) {
Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => {
eprintln!("file too small for footer, restoring from backup");
}
Err(e) => return Err(e),
Ok((footer, rest)) => (footer, rest),
} Prevention
- Validate the index directory (all segment sizes > 0) before opening
- Ensure completed writes: fsync and atomic rename on publish
- Detect disk-full conditions during indexing
- Keep verified backups of index directories
When it happens
Trigger: Calling extract_footer (or opening an index) on a zero-length or 1-3 byte file: empty file created by a failed write, placeholder/lock files misread as segments, truncated uploads.
Common situations: Disk-full or crash during index write leaving empty files; incomplete rsync/scp of the index directory; pointing tantivy at the wrong directory containing stray empty files.
Related errors
- InvalidData
- UnexpectedEof
- UnexpectedEof
- File corrupted. The file is smaller than Footer::SIZE_IN_BYT
- Corrupted data. Invalid VInt 32
AI-assisted analysis of quickwit-oss/tantivy@b5d8deb80c (2026-09-05).
Data as JSON: /api/errors/75348127f8438b91.
Report an issue: GitHub.