nautechsystems/nautilus_trader · error · anyhow::Error
URI {path} uses non-remote scheme {} for remote catalog at {
Error message
URI {path} uses non-remote scheme {} for remote catalog at {} What it means
The persistence catalog is backed by a remote object store (S3, GCS, etc.), and it validates that any URI passed to `object_store_path` uses a recognized remote scheme. When the parsed path's scheme (e.g. `file`, `http`, `sftp`, or a relative path defaulting to `file`) is not in the remote-scheme allowlist, the catalog refuses to map it to an object-store path. This prevents accidentally writing parquet data to a local disk or unsupported store when the catalog is configured for a remote backend.
Source
Thrown at crates/persistence/src/backend/catalog.rs:3054
let normalized_path = path.replace('\\', "/");
if self.is_remote_uri() {
if normalized_path.contains("://") {
let path_under_root = self.remote_uri_object_path(&normalized_path)?;
return Ok(self.path_under_base(&path_under_root));
}
return Ok(self.path_under_base(&normalized_path));
}
Ok(self.path_without_local_base(&normalized_path))
}
fn remote_uri_object_path(&self, path: &str) -> anyhow::Result<String> {
let path_url = url::Url::parse(path)
.map_err(|e| anyhow::anyhow!("Failed to parse object store URI {path}: {e}"))?;
if !is_remote_uri_scheme(path_url.scheme()) {
anyhow::bail!(
"URI {path} uses non-remote scheme {} for remote catalog at {}",
path_url.scheme(),
self.original_uri,
);
}
let catalog_root = remote_store_root_url(&self.original_uri)?;
let path_root = remote_store_root_url(path)?;
if catalog_root.as_str().trim_end_matches('/') != path_root.as_str().trim_end_matches('/') {
anyhow::bail!(
"Cross-store URI {path} (root {}) does not belong to catalog rooted at {} ({})",
path_root.as_str().trim_end_matches('/'),
self.original_uri,
catalog_root.as_str().trim_end_matches('/'),
);
}
// The URL crate keeps the path component percent-encoded (e.g. `%5E`),View on GitHub (pinned to 18893faf8b)
Solutions
- Fix the path to use the same remote scheme as the catalog (e.g. `s3://bucket/path/to/file.parquet`) instead of `file://` or a relative path.
- Check for typos in the URI scheme (`s3`, `gs`, `azure`, per the library's supported remote schemes) and correct it.
- If a local catalog is intended, construct the catalog with the local URI so the remote validation path is not used.
Example fix
// before
catalog.object_store_path("file:///home/user/data/quotes.parquet");
// after
catalog.object_store_path("s3://my-bucket/data/quotes.parquet"); Defensive patterns
Strategy: validation
Validate before calling
// Rust
fn is_remote(path: &str) -> bool {
url::Url::parse(path)
.map(|u| matches!(u.scheme(), "s3" | "gs" | "az" | "abfs" | "memory"))
.unwrap_or(false)
}
// call catalog.object_store_path(p) only if is_remote(p) Type guard
fn assert_remote_uri(path: &str) -> Option<url::Url> {
url::Url::parse(path).ok().filter(|u| !matches!(u.scheme(), "file" | "http" | "https"))
} Prevention
- Build object-store paths from the catalog URI itself (join on the catalog root) rather than hardcoding `file://` or relative paths.
- Validate URI schemes at config load time, before constructing the catalog.
- Add a startup assertion that all configured data paths share the catalog's scheme.
When it happens
Trigger: Calling `catalog.object_store_path(path)` (via `remote_uri_object_path`) with a path whose URL scheme is not a remote scheme — e.g. a local `file:///data/catalog` path, a relative path like `./data`, an `http(s)://` URL, or a typo'd scheme like `s3x://bucket/key`.
Common situations: Developers mixing local and remote config: a catalog built with `s3://` URI but the queried/written path still points at a local file; path variables inherited from old local-catalog code; typos in bucket URIs (`s2://`); using `file://` URIs copied from local test setups against a production remote catalog.
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
- Cross-store URI {path} (root {}) does not belong to catalog
- replace_existing for remote streaming paths requires a non-e
- Unsupported blockchain {blockchain} for RPC connection
- Kraken Spot does not support the demo environment
- Redis config error: username supplied without password. Eith
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5a4c863357eff852.
Report an issue: GitHub.