nautechsystems/nautilus_trader · error · anyhow::Error

Failed to parse Databento Historical API base URL: {e}

Error message

Failed to parse Databento Historical API base URL: {e}

What it means

Thrown when the `base_url` string passed to `new_with_base_url` cannot be parsed into the URL type the databento HistoricalClient builder expects. The parse error is embedded in the message. This only occurs on the base-URL variant of the constructor, not the default `new`.

Source

Thrown at crates/adapters/databento/src/historical.rs:141

    /// Creates a new [`DatabentoHistoricalClient`] instance with a custom API base URL.
    ///
    /// This is intended for tests, benchmarks, and controlled deployments that route
    /// Databento Historical API requests through a proxy.
    ///
    /// # Errors
    ///
    /// Returns an error if client creation, URL parsing, or publisher loading fails.
    pub fn new_with_base_url(
        credential: Credential,
        publishers_filepath: PathBuf,
        clock: &'static AtomicTime,
        use_exchange_as_venue: bool,
        base_url: &str,
    ) -> anyhow::Result<Self> {
        let client = databento::HistoricalClient::builder()
            .user_agent_extension(NAUTILUS_USER_AGENT.into())
            .base_url(base_url.parse().map_err(|e| {
                anyhow::anyhow!("Failed to parse Databento Historical API base URL: {e}")
            })?)
            .key(credential.api_key())
            .map_err(|e| anyhow::anyhow!("Failed to create client builder: {e}"))?
            .build()
            .map_err(|e| anyhow::anyhow!("Failed to build client: {e}"))?;

        Self::from_client(
            credential,
            publishers_filepath,
            clock,
            use_exchange_as_venue,
            client,
        )
    }

    fn from_client(
        credential: Credential,
        publishers_filepath: PathBuf,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Include the scheme: use 'https://...' or 'http://...' for the base URL
  2. Trim whitespace and quotes from the URL before passing it
  3. Validate the URL with `url::Url::parse` before calling the constructor
  4. Check the config file/env var that supplies the base URL for typos

Example fix

// before
let base_url = "localhost:8080";
client.new_with_base_url(cred, path, clock, true, base_url)
// after
let base_url = "http://localhost:8080";
url::Url::parse(base_url).expect("valid base url");
client.new_with_base_url(cred, path, clock, true, base_url)
Defensive patterns

Strategy: validation

Validate before calling

let parsed = url::Url::parse(base_url)?;
if !matches!(parsed.scheme(), "http" | "https") {
    return Err(anyhow::anyhow!("base_url must use http(s): {base_url}"));
}

Type guard

fn is_valid_base_url(s: &str) -> bool {
    url::Url::parse(s).map(|u| matches!(u.scheme(), "http" | "https")).unwrap_or(false)
}

Prevention

When it happens

Trigger: Calling `new_with_base_url(credential, ..., base_url)` with a string that is not a valid absolute URL (e.g. missing scheme, invalid characters).

Common situations: Pointing at a local mock/proxy server with 'localhost:8080' (missing http://), typo'd scheme ('htp://'), trailing garbage, or a config value that was meant to be host-only.

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/31ec97a1bbfafba1. Report an issue: GitHub.