nautechsystems/nautilus_trader · error · anyhow::Error

{error_msg}

Error message

{error_msg}

What it means

extract_host is a shared helper that pulls the host string from a parsed url::Url; if the URL has no host (host_str() returns None), it raises the caller-provided error message. All cloud store builders (S3, GCS, Azure, ABFS) route through it, so this surfaces as 'Invalid ... URI: missing host'.

Source

Thrown at crates/persistence/src/parquet.rs:995

    let http_store = builder.build()?;
    Ok((Arc::new(http_store), path, uri.to_string()))
}

/// Parses a URL and extracts its path component.
#[cfg(feature = "cloud")]
fn parse_url_and_path(uri: &str) -> anyhow::Result<(url::Url, String)> {
    let url = url::Url::parse(uri)?;
    let path = url.path().trim_start_matches('/').to_string();
    Ok((url, path))
}

/// Extracts the host from a URL.
#[cfg(feature = "cloud")]
fn extract_host(url: &url::Url, error_msg: &str) -> anyhow::Result<String> {
    url.host_str()
        .map(ToString::to_string)
        .ok_or_else(|| anyhow::anyhow!("{error_msg}"))
}

#[cfg(test)]
mod tests {
    #[cfg(feature = "cloud")]
    use ahash::AHashMap;
    use arrow::{
        array::Int64Array,
        datatypes::{DataType, Field, Schema},
    };
    use rstest::rstest;

    use super::*;

    #[rstest]
    fn test_create_object_store_from_path_local() {
        // Create a temporary directory for testing
        let temp_dir = std::env::temp_dir().join("nautilus_test");

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Include a host in the URI: s3://bucket/key, gs://bucket/key, abfss://container@account.dfs.core.windows.net/path
  2. Log the URI string and parsed host before constructing the store
  3. Validate with url::Url::parse(...).host_str().is_some() before calling
  4. Ensure storage options (endpoint_url etc.) are not empty strings that corrupt the URI

Example fix

// before
let uri = "s3:///nautilus-data"; // no host
// after
let uri = "s3://nautilus-data";
Defensive patterns

Strategy: validation

Validate before calling

let url = url::Url::parse(uri)?;
anyhow::ensure!(url.host_str().is_some(), "URI '{uri}' has no host");

Type guard

fn has_host(s: &str) -> bool {
    url::Url::parse(s).ok().and_then(|u| u.host_str().map(|_| ())).is_some()
}

Try / catch

let store = create_object_store_location_from_path(uri, None)
    .unwrap_or_else(|e| panic!("bad cloud URI '{uri}': {e}"));

Prevention

When it happens

Trigger: Calling create_s3_store / create_gcs_store / create_azure_store / create_abfs_store with a URI the url crate parses without a host — e.g. 's3:///bucket/key', relative paths, or schemes like 'file://' passed to a cloud builder.

Common situations: Environment/config typo dropping the endpoint host; hand-assembled URIs with triple slashes; using a local path where a cloud URI is expected; overriding endpoint with an empty value.

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/2586aac957b96bac. Report an issue: GitHub.