nautechsystems/nautilus_trader · error · anyhow::Error

Failed to get dataset range: {e}

Error message

Failed to get dataset range: {e}

What it means

Wraps a failure from the Databento Metadata API call `get_dataset_range`, which returns the first-to-last available date range for a dataset. The databento error (network, auth, or API-level) is embedded in the message. Raised in `DatabentoHistoricalClient::get_dataset_range`.

Source

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

        }

        let precision = self.resolve_price_precision(instrument_id, None)?;
        precision_cache.insert(*instrument_id, precision);
        Ok(precision)
    }

    /// Gets the date range for a specific dataset.
    ///
    /// # Errors
    ///
    /// Returns an error if the API request fails.
    pub async fn get_dataset_range(&self, dataset: &str) -> anyhow::Result<DatasetRange> {
        let mut client = (*self.inner).clone();
        let response = client
            .metadata()
            .get_dataset_range(dataset)
            .await
            .map_err(|e| anyhow::anyhow!("Failed to get dataset range: {e}"))?;

        Ok(DatasetRange {
            start: response.start.to_string(),
            end: response.end.to_string(),
        })
    }

    /// Fetches instrument definitions for the given parameters.
    ///
    /// # Errors
    ///
    /// Returns an error if the API request or data processing fails.
    pub async fn get_range_instruments(
        &self,
        params: RangeQueryParams,
    ) -> anyhow::Result<Vec<InstrumentAny>> {
        let symbols: Vec<&str> = params.symbols.iter().map(String::as_str).collect();
        check_consistent_symbology(&symbols)?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the embedded `{e}` to distinguish auth vs network vs API error
  2. Verify the dataset code against Databento's documented dataset list
  3. Confirm the API key has access/licensing for that dataset
  4. Retry on transient network errors; check connectivity/proxy settings

Example fix

// before
let range = client.get_dataset_range("GLBX.MDP3").await?;
// after
match client.get_dataset_range("GLBX.MDP3").await {
    Ok(range) => range,
    Err(e) => { log::error!("dataset range failed: {e:#}"); return Err(e); }
}
Defensive patterns

Strategy: retry

Validate before calling

// dataset codes look like 'GLBX.MDP3'
if dataset.is_empty() || !dataset.contains('.') {
    bail!("suspect dataset code: {dataset}");
}

Type guard

fn looks_like_dataset_code(s: &str) -> bool {
    !s.is_empty() && s.contains('.') && s.chars().all(|c| c.is_ascii_alphanumeric() || c == '.' || c == '_')
}

Try / catch

let range = loop {
    match client.get_dataset_range(dataset).await {
        Ok(r) => break r,
        Err(e) if is_transient(&e) => { tokio::time::sleep(Duration::from_secs(2)).await; }
        Err(e) => return Err(e),
    }
};

Prevention

When it happens

Trigger: Calling `get_dataset_range(dataset)` where the HTTP request fails: invalid API key, unknown/misspelled dataset code, network outage, or Databento API returning an error status.

Common situations: Typo'd dataset codes (e.g. 'GLBX.MDP3' misspelled), expired credentials, rate limiting, corporate proxy blocking HTTPS egress.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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