nautechsystems/nautilus_trader · error · anyhow::Error

Failed to build client: {e}

Error message

Failed to build client: {e}

What it means

Wraps any error returned by the databento crate's HistoricalClient builder's `.build()` step into an anyhow error with a unified message. The underlying databento error is preserved via Display in the message. Thrown from `DatabentoHistoricalClient::new` when the configured builder cannot construct a client (e.g. invalid API key format).

Source

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

    }

    /// Creates a new [`DatabentoHistoricalClient`] instance.
    ///
    /// # Errors
    ///
    /// Returns an error if client creation or publisher loading fails.
    pub fn new(
        credential: Credential,
        publishers_filepath: PathBuf,
        clock: &'static AtomicTime,
        use_exchange_as_venue: bool,
    ) -> anyhow::Result<Self> {
        let client = databento::HistoricalClient::builder()
            .user_agent_extension(NAUTILUS_USER_AGENT.into())
            .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,
        )
    }

    /// 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.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Print/log the underlying `{e}` to see the exact databento builder error
  2. Verify the API key is non-empty, correctly formatted, and active on your Databento account
  3. Re-export the DATABENTO_API_KEY environment variable and rebuild the credential
  4. Check databento crate version for changed builder build() requirements

Example fix

// before
let key = std::env::var("DATABENTO_API_KEY").unwrap_or_default();
// after
let key = std::env::var("DATABENTO_API_KEY").expect("DATABENTO_API_KEY must be set");
let key = key.trim();
assert!(!key.is_empty(), "DATABENTO_API_KEY is empty");
Defensive patterns

Strategy: try-catch

Validate before calling

let key = std::env::var("DATABENTO_API_KEY")?;
if key.trim().is_empty() { return Err(anyhow::anyhow!("DATABENTO_API_KEY is empty")); }

Type guard

fn has_api_key(cred: &Credentials) -> bool { !cred.api_key().trim().is_empty() }

Try / catch

match DatabentoHistoricalClient::new(cred, path, clock, true) {
    Ok(c) => c,
    Err(e) => { eprintln!("client init failed: {e:#}"); return Err(e); }
}

Prevention

When it happens

Trigger: Calling `DatabentoHistoricalClient::new(credential, ...)` where the credential's API key is rejected by the databento builder's build() validation (e.g. empty or malformed key).

Common situations: Expired or revoked Databento API keys, keys copied with whitespace, using an environment variable that is unset/empty so the key resolves to an invalid value.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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