quickwit-oss/quickwit · error
URI `{uri}` is not a valid file URI
Error message
URI `{uri}` is not a valid file URI What it means
load_file splits the URI into a parent directory (to resolve a storage) and a file name (to fetch). If uri.parent() returns None — the URI has no separable parent, e.g. a bare scheme-less or root-less URI — the function cannot determine which storage to use and fails with this anyhow error.
Source
Thrown at quickwit/quickwit-storage/src/lib.rs:109
#[cfg(feature = "integration-testsuite")]
pub use self::test_suite::{
storage_test_multi_part_upload, storage_test_single_part_upload, storage_test_suite,
test_write_and_bulk_delete,
};
pub use self::timeout_and_retry_storage::TimeoutAndRetryStorage;
pub use crate::error::{
BulkDeleteError, DeleteFailure, StorageError, StorageErrorKind, StorageResolverError,
StorageResult,
};
/// Loads an entire local or remote file into memory.
pub async fn load_file(
storage_resolver: &StorageResolver,
uri: &Uri,
) -> anyhow::Result<OwnedBytes> {
let parent = uri
.parent()
.ok_or_else(|| anyhow::anyhow!("URI `{uri}` is not a valid file URI"))?;
let storage = storage_resolver.resolve(&parent).await?;
let file_name = uri
.file_name()
.ok_or_else(|| anyhow::anyhow!("URI `{uri}` is not a valid file URI"))?;
let bytes = storage.get_all(file_name).await?;
Ok(bytes)
}
// this function isn't meant to be called, just to break compilation if
// serde_json::Map is an ordered map and not a btree map
#[allow(dead_code)]
#[cfg(not(any(test, feature = "testsuite", feature = "integration-testsuite")))]
unsafe fn serde_json_preserve_order_canary(
val: serde_json::Map<String, serde_json::Value>,
) -> std::collections::BTreeMap<String, serde_json::Value> {
use std::mem::transmute as assert_serde_json__preserve_order__disabled;
unsafe { assert_serde_json__preserve_order__disabled(val) }
}View on GitHub (pinned to a39730c5cd)
Solutions
- Pass a fully-qualified URI including at least a parent directory, e.g. file:///etc/quickwit/config.yaml or s3://bucket/path/config.yaml.
- If using a local path, prefix it with file:// or use an absolute path so parent() resolves.
- Echo the URI variable before invoking the CLI to catch empty or truncated values from shell expansion.
- Validate the URI with Uri::parse or similar before calling load_file programmatically.
Example fix
// before
let config = load_file(&resolver, &"quickwit.yaml".into()).await?;
// after
let uri = Uri::parse("file:///etc/quickwit/quickwit.yaml")?;
let config = load_file(&resolver, &uri).await?; Defensive patterns
Strategy: validation
Validate before calling
if uri.as_str().is_empty() || !uri.as_str().contains('/') {
anyhow::bail!("URI `{}` must include a parent directory, e.g. file:///path/config.yaml", uri);
} Type guard
fn has_parent(uri: &Uri) -> bool {
uri.parent().is_some()
} Try / catch
let config = load_file(&resolver, &uri).await.map_err(|e| {
anyhow::anyhow!("failed to load config from `{uri}`: {e} (use a full URI like file:///etc/quickwit/quickwit.yaml)")
})?; Prevention
- Always pass fully-qualified URIs (file:// or s3://bucket/key) to CLIs, never bare file names.
- Echo shell variables used for URIs to catch empty expansions.
- Validate URIs with Uri::parse before calling load_file programmatically.
When it happens
Trigger: Calling load_file with a URI whose parent() is None, such as "file.txt" (no scheme/separator), an empty URI, or "s3://" with no path component. Reached from create_index_cli, update_index_cli, load_node_config, create_source_cli, and update_source_cli when a --config or index-config URI is malformed.
Common situations: Passing a bare relative file name on the CLI instead of a full URI like file:///path/to/config.yaml or /abs/path/config.yaml; forgetting the scheme or path when pointing at an S3-hosted config; shell variable expansion leaving the URI empty.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- unknown URI protocol `{protocol}`
- `append_records` should be called with `position_opt: None`
- failed to run mrecordlog operation
- stdin cannot be checkpointed
- Unexpected span kind: {}
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/4b1c71d571397c11.
Report an issue: GitHub.