quickwit-oss/quickwit · error · StorageError

missing file `{}`

Error message

missing file `{}`

What it means

BundleStorage's get_slice looks up the requested path in its in-memory file_ranges map; when the file is not part of the bundle it returns StorageErrorKind::NotFound. Only files recorded in the bundle footer exist through this storage view — the bundle is a single physical file exposing many logical files as byte ranges.

Source

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

    ) -> crate::StorageResult<()> {
        let file_len = self.file_num_bytes(path).await? as usize;
        let block_size = 100_000_000;
        for block in chunk_range(0..file_len, block_size) {
            let file_content = self.get_slice(path, block).await?;
            output.write_all(&file_content).await?;
        }
        output.flush().await?;
        Ok(())
    }

    async fn get_slice(
        &self,
        path: &Path,
        range: Range<usize>,
    ) -> crate::StorageResult<OwnedBytes> {
        let file_range = self.file_ranges.get(path).ok_or_else(|| {
            crate::StorageErrorKind::NotFound
                .with_error(anyhow::anyhow!("missing file `{}`", path.display()))
        })?;
        let new_range =
            file_range.start as usize + range.start..file_range.start as usize + range.end;
        self.storage
            .get_slice(&self.bundle_filepath, new_range)
            .await
    }

    async fn get_slice_stream(
        &self,
        path: &Path,
        _range: Range<usize>,
    ) -> StorageResult<Box<dyn AsyncRead + Send + Unpin>> {
        Err(unsupported_operation(&[path]))
    }

    async fn get_all(&self, path: &Path) -> crate::StorageResult<OwnedBytes> {
        let file_range = self.file_ranges.get(path).ok_or_else(|| {

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Log the requested path and enumerate self.file_ranges keys to compare exact spellings; fix the caller to use the recorded name.
  2. Verify the bundle's footer parsed completely — a truncated footer yields a partial file_ranges map; re-upload or restore the bundle.
  3. Check for version skew: the requested file may genuinely not exist in bundles written by the deployed indexer version.
  4. Fall back to fetching the file from the standalone storage location if your deployment stores unbundled files.

Example fix

// before: assume the file is always bundled
let bytes = bundle_storage.get_slice(path, range).await?;
// after: check membership first
if !bundle_storage.exists(path) {
    return Err(anyhow::anyhow!("file {} not in bundle {}", path, bundle_uri));
}
let bytes = bundle_storage.get_slice(path, range).await?;
Defensive patterns

Strategy: validation

Validate before calling

if !bundle_storage.exists(path) {
    anyhow::bail!("file {} is not packaged in bundle {}", path, bundle_storage.uri());
}

Type guard

fn is_bundled(bundle: &BundleStorage, path: &Path) -> bool {
    bundle.exists(path)
}

Try / catch

match bundle_storage.get_slice(path, range).await {
    Err(e) if e.kind() == quickwit_storage::StorageErrorKind::NotFound => {
        // fall back or report missing file
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling BundleStorage::get_slice (directly or via copy_to) with a path that was never packaged into the bundle, or a path spelled differently from the one recorded at packaging time (leading './', different casing, missing directory prefix).

Common situations: A searcher requesting a hotcache/meta file name that does not match the bundled name; version skew where a newer format expects a file absent from bundles written by an older indexer; a bundle footer that was truncated so only some file ranges were parsed.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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