quickwit-oss/quickwit · error · StorageError
file `{}` is not a regular file, cannot determine its size
Error message
file `{}` is not a regular file, cannot determine its size What it means
`file_num_bytes` on LocalFileStorage stats the path with `tokio::fs::metadata` and refuses to return a size if the target is not a regular file (directory, fifo, socket, device). It maps that case to a NotFound StorageError rather than returning a meaningless byte count.
Source
Thrown at quickwit/quickwit-storage/src/local_file_storage.rs:350
}
fn uri(&self) -> &Uri {
&self.uri
}
#[tracing::instrument(
name = "storage.local_file.file_num_bytes",
level = "debug",
skip(self)
)]
async fn file_num_bytes(&self, path: &Path) -> StorageResult<u64> {
let full_path = self.full_path(path)?;
match tokio::fs::metadata(full_path).await {
Ok(metadata) => {
if metadata.is_file() {
Ok(metadata.len())
} else {
Err(StorageErrorKind::NotFound.with_error(anyhow::anyhow!(
"file `{}` is not a regular file, cannot determine its size",
path.display()
)))
}
}
Err(err) => {
if err.kind() == ErrorKind::NotFound {
Err(StorageErrorKind::NotFound.with_error(err))
} else {
Err(err.into())
}
}
}
}
}
/// A File storage resolver
#[derive(Clone, Debug, Default)]View on GitHub (pinned to a39730c5cd)
Solutions
- Verify the path points to an actual file, not a directory (`file <path>` or `ls -l`)
- Correct the index/storage URI in the config so it references files, not directories
- If a symlink is involved, confirm it resolves to a regular file
- Handle the NotFound StorageErrorKind in the caller if probing optional paths
Example fix
// before
let size = storage.file_num_bytes(&dir_path).await?;
// after
if tokio::fs::metadata(&dir_path).await.map(|m| m.is_file()).unwrap_or(false) {
let size = storage.file_num_bytes(&dir_path).await?;
} Defensive patterns
Strategy: validation
Validate before calling
let md = tokio::fs::metadata(&path).await?;
if !md.is_file() {
return Err(anyhow::anyhow!("{} is not a regular file", path.display()));
}
let expected_len = md.len(); Type guard
fn is_regular_file(md: &std::fs::Metadata) -> bool { md.is_file() } Try / catch
match storage.file_num_bytes(&path).await {
Ok(len) => use(len),
Err(e) if e.kind() == StorageErrorKind::NotFound => skip_or_recreate(path),
Err(e) => return Err(e.into()),
} Prevention
- Point index/storage URIs at file paths, never directories or special files
- Check symlink targets resolve to regular files before wiring them into config
- Probe optional paths with kind()==NotFound handling instead of assuming existence
- Keep regular files and directories in clearly separated prefixes
When it happens
Trigger: Calling `Storage::file_num_bytes` (or APIs that stat objects, e.g. delete/list flows using sizes) with a path that resolves to a directory or special file instead of a regular file.
Common situations: Misconfigured index URI pointing at a directory instead of the index root's files; a path that was expected to be a file but is a symlink target that became a directory; passing a prefix/directory path to a size-query API.
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
- `{}` not found in storage
- missing file `{}`
- reading file panicked
- failed to find dest_path {:?}
- `append_records` should be called with `position_opt: None`
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/744764c8cc310b1a.
Report an issue: GitHub.