{"record":{"id":"a60e492fb3919965","repo":"quickwit-oss/quickwit","slug":"bundled-file-range-overlaps-split-footer","errorCode":null,"errorMessage":"bundled file range overlaps split footer","messagePattern":"bundled file range overlaps split footer","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-storage/src/bundle_storage.rs","lineNumber":134,"sourceCode":"            DEFAULT_SPLIT_TAIL_WINDOW_NUM_BYTES,\n        )\n        .await?;\n\n        // Parse the bundle file ranges from the split bytes.\n        let tail_start = split_len - split_bytes.len() as u64;\n        let (file_ranges, _hotcache) =\n            BundleFileRanges::open_from_split_bytes(split_bytes.clone())?;\n        let file_range = file_ranges.get(&bundle_filepath).ok_or_else(|| {\n            anyhow::anyhow!(\n                \"missing file `{}` in split bundle\",\n                bundle_filepath.display()\n            )\n        })?;\n        ensure!(\n            file_range.start <= file_range.end,\n            \"bundled file range starts after it ends\"\n        );\n        ensure!(\n            file_range.end <= footer_range.start,\n            \"bundled file range overlaps split footer\"\n        );\n\n        // If the initial tail also contains the file, reuse it and complete in one GET (at least).\n        // Otherwise, fetch the file with an additional GET.\n        let file_bytes = if file_range.start >= tail_start {\n            let relative_start = (file_range.start - tail_start) as usize;\n            let relative_end = (file_range.end - tail_start) as usize;\n            split_bytes.slice(relative_start..relative_end)\n        } else {\n            let relative_start = file_range.start as usize;\n            let relative_end = file_range.end as usize;\n            storage\n                .get_slice(split_path, relative_start..relative_end)\n                .await?\n        };\n        Ok((file_bytes, footer_range))","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-storage/src/bundle_storage.rs#L116-L152","documentation":"After locating the file's byte range and the split footer range, bundle storage requires the bundled file to lie entirely before the footer. If file_range.end exceeds footer_range.start, the file range overlaps the split footer (hotcache/bundle metadata) region, meaning the bundle metadata is inconsistent. Throwing prevents reading footer bytes as file content.","triggerScenarios":"Calling `fetch_file_from_split` on a split where the recorded file range crosses into the footer region — caused by corrupted or malformed bundle metadata in the split footer.","commonSituations":"Splits written with a buggy writer version; object-storage objects partially overwritten so the footer moved but file ranges didn't; manual manipulation of split files.","solutions":["Re-index or re-upload the split so its bundle metadata is regenerated consistently.","Verify the split's checksum against the metastore/manifest to confirm corruption before replacing it.","Check the writing Quickwit version for known bundle-footer bugs and upgrade if affected."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match bundle_storage.fetch_file_from_split(split, path).await {\n    Ok(bytes) => bytes,\n    Err(e) if e.to_string().contains(\"overlaps split footer\") => {\n        // treat split as corrupted; re-index or re-upload\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Verify split checksums when copying objects between buckets.","Never overwrite an existing split object in place; write a new object instead.","Run the same Quickwit version cluster-wide to avoid writer/reader layout drift."],"tags":["storage","split-bundle","corruption"],"backgroundTag":"internal-invariant-violation","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}