quickwit-oss/quickwit · error

failed to locate split footer after reading bundle metadata

Error message

failed to locate split footer after reading bundle metadata length

What it means

Hotcache/split fetch reads the split's tail to locate the bundle footer. After re-reading an extended tail that includes the bundle metadata length, `locate_split_footer_range_in_tail` still could not produce a Located footer range. This means the split tail bytes do not contain a consistent bundle/footer structure, so `fetch_split_tail` aborts instead of guessing offsets.

Source

Thrown at quickwit/quickwit-storage/src/bundle_storage.rs:335

    let mut tail_bytes =
        read_split_tail(storage, split_path, split_len, initial_tail_num_bytes).await?;

    // Locate the footer range.
    let footer_range = match locate_split_footer_range_in_tail(split_len, &tail_bytes)? {
        FooterLocation::Located(footer_range) => {
            // The range is known, but the initial tail may not contain the complete footer.
            footer_range
        }
        FooterLocation::ReadBundleMetadataLen(bundle_metadata_len_range) => {
            // Extend the tail through the legacy bundle-metadata length field, then use that
            // length to locate the beginning of the footer.
            let required_tail_num_bytes = split_len - bundle_metadata_len_range.start;
            let metadata_len_tail_bytes =
                read_split_tail(storage, split_path, split_len, required_tail_num_bytes).await?;
            match locate_split_footer_range_in_tail(split_len, &metadata_len_tail_bytes)? {
                FooterLocation::Located(footer_range) => footer_range,
                FooterLocation::ReadBundleMetadataLen(_) => {
                    bail!("failed to locate split footer after reading bundle metadata length");
                }
            }
        }
    };

    // If the initial tail does not contain the entire footer, fetch the exact footer range now
    // that its boundaries are known.
    let footer_num_bytes = footer_range.end - footer_range.start;
    if (tail_bytes.len() as u64) < footer_num_bytes {
        tail_bytes = read_split_tail(storage, split_path, split_len, footer_num_bytes).await?;
    }
    Ok((tail_bytes, footer_range))
}

async fn read_split_tail(
    storage: &dyn Storage,
    split_path: &Path,
    split_len: u64,

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Verify split integrity (footer/checksum); re-upload or re-index the split from source data.
  2. Confirm the split was written by a compatible Quickwit version; upgrade or downgrade as needed.
  3. Check storage consistency: retry the fetch if a transient partial read is suspected, then treat persistent failure as corruption.
Defensive patterns

Strategy: try-catch

Try / catch

match fetch_file_from_split(...).await {
    Err(e) if e.to_string().contains("failed to locate split footer") => {
        // mark split as corrupted, trigger re-index
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling fetch_file_from_split on a split whose tail was truncated/corrupted, whose footer was overwritten, or whose on-disk format predates/differs from the footer layout the reader expects, such that even after reading the bundle metadata length the footer range can't be located.

Common situations: Partially uploaded or truncated splits in object storage; corrupted split files; version mismatch between the code reading splits and splits written by an older Quickwit format.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08). Data as JSON: /api/errors/c7963b70ec7f49b4. Report an issue: GitHub.