nautechsystems/nautilus_trader · error · anyhow::Error

Failed to fetch products: {e}

Error message

Failed to fetch products: {e}

What it means

CoinbaseInstrumentProvider::load_all fetches the full products list via the HTTP client's get_products endpoint. Any transport-level failure — network error, DNS failure, TLS problem, timeout, non-success HTTP status surfaced as a client error — is wrapped into this anyhow error. It means the request itself failed before any parsing happened.

Source

Thrown at crates/adapters/coinbase/src/provider.rs:80

    }

    /// Returns a cached instrument by ID, if present.
    #[must_use]
    pub fn get(&self, instrument_id: &InstrumentId) -> Option<InstrumentAny> {
        self.client.instruments().get_cloned(instrument_id)
    }

    /// Loads all instruments from the Coinbase REST API and caches them.
    ///
    /// # Errors
    ///
    /// Returns an error if the HTTP request fails or the response cannot be parsed.
    pub async fn load_all(&self) -> anyhow::Result<Vec<InstrumentAny>> {
        let json = self
            .client
            .get_products()
            .await
            .map_err(|e| anyhow::anyhow!("Failed to fetch products: {e}"))?;

        self.load_from_products_response(&json)
    }

    /// Loads all instruments of a specific product type from the REST API.
    ///
    /// # Errors
    ///
    /// Returns an error if the HTTP request fails or the response cannot be parsed.
    pub async fn load_all_filtered(
        &self,
        product_type: CoinbaseProductType,
    ) -> anyhow::Result<Vec<InstrumentAny>> {
        let json = self
            .client
            .get_products()
            .await
            .map_err(|e| anyhow::anyhow!("Failed to fetch products: {e}"))?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the wrapped source error ({e}) to see the exact HTTP/network cause.
  2. Verify network connectivity, proxy settings, and that the Coinbase API base URL is reachable (curl the products endpoint).
  3. Check API key/secret configuration if the endpoint requires authentication.
  4. Add retry with backoff for transient failures (429/5xx/timeouts).

Example fix

// before
let instruments = provider.load_all().await?;
// after
let instruments = match provider.load_all().await {
    Ok(i) => i,
    Err(e) => {
        tracing::error!("products fetch failed: {e:#}");
        if e.to_string().contains("429") {
            tokio::time::sleep(Duration::from_secs(5)).await;
            provider.load_all().await?
        } else {
            return Err(e);
        }
    }
};
Defensive patterns

Strategy: retry

Validate before calling

async fn products_reachable(base: &str) -> bool {
    reqwest::get(format!("{base}/products")).await.map(|r| r.status().is_success()).unwrap_or(false)
}
assert!(products_reachable("https://api.coinbase.com").await, "Coinbase API unreachable");

Try / catch

match provider.load_all().await {
    Ok(instruments) => instruments,
    Err(e) => {
        warn!("products fetch failed: {e:#}");
        backoff_retry(|| provider.load_all(), 3).await?
    }
}

Prevention

When it happens

Trigger: Calling load_all() when the Coinbase REST endpoint is unreachable, the API returns 4xx/5xx, rate limits are hit, TLS/timeouts occur, or no network is available.

Common situations: Running without internet or behind a corporate proxy; missing/invalid Coinbase API credentials causing 401; hitting the public rate limit (429); Coinbase incident/outage; wrong base URL in client configuration.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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