nautechsystems/nautilus_trader · error

Failed to create HTTP client: {e}

Error message

Failed to create HTTP client: {e}

What it means

BetfairHttpClient::new could not build the underlying rate-limited HttpClient. The dominant cause is quota construction: make_quota requires request_rate_per_second and order_request_rate_per_second to be non-zero (NonZeroU32), so a configured 0 fails with 'must be greater than zero'. Other transport-construction failures (e.g. an unusable proxy_url) surface through the same wrapped message.

Source

Thrown at crates/adapters/betfair/src/http/client.rs:130

            jitter_ms: 500,
            operation_timeout_ms: Some(30_000),
            immediate_first: false,
            max_elapsed_ms: Some(120_000),
        };

        Ok(Self {
            client: HttpClient::new(
                HashMap::new(),
                Vec::new(),
                Self::rate_limiter_quotas(
                    request_rate_per_second.unwrap_or(5),
                    order_request_rate_per_second.unwrap_or(20),
                )?,
                Self::default_quota(request_rate_per_second.unwrap_or(5))?,
                timeout_secs,
                proxy_url,
            )
            .map_err(|e| anyhow::anyhow!("Failed to create HTTP client: {e}"))?,
            credential,
            session_token: Arc::new(tokio::sync::RwLock::new(None)),
            retry_manager: RetryManager::new(retry_config),
            cancellation_token: std::sync::Mutex::new(CancellationToken::new()),
            connect_lock: tokio::sync::Mutex::new(()),
            request_id: AtomicU64::new(1),
            url_identity_login: BETFAIR_IDENTITY_LOGIN_URL.to_string(),
            url_keep_alive: BETFAIR_KEEP_ALIVE_URL.to_string(),
            url_betting: BETFAIR_BETTING_URL.to_string(),
            url_accounts: BETFAIR_ACCOUNTS_URL.to_string(),
            url_navigation: BETFAIR_NAVIGATION_URL.to_string(),
        })
    }

    /// Overrides the API base URLs (for testing with mock servers).
    ///
    /// The keep-alive URL is derived from `identity_login` by replacing the
    /// path with `/keepAlive`.

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Set both rate options to positive values (defaults are 5 and 20 requests/sec) or leave them unset to use the defaults.
  2. Validate config values in BetfairDataConfig/BetfairExecConfig::validate before client creation.
  3. Remove or fix proxy_url if provided.

Example fix

// before
let config = BetfairExecConfig {
    request_rate_per_second: Some(0), // 'unlimited' -> rejected
    order_request_rate_per_second: Some(0),
    ..Default::default()
};

// after
let config = BetfairExecConfig {
    request_rate_per_second: Some(5),
    order_request_rate_per_second: Some(20),
    ..Default::default()
};
Defensive patterns

Strategy: validation

Validate before calling

fn rates_valid(request_rate: Option<u32>, order_rate: Option<u32>) -> bool {
    request_rate.unwrap_or(5) > 0 && order_rate.unwrap_or(20) > 0
}

if !rates_valid(config.request_rate_per_second, config.order_request_rate_per_second) {
    return Err(anyhow::anyhow!("rate limits must be > 0"));
}

Prevention

When it happens

Trigger: Creating the Betfair data or execution client with request_rate_per_second: Some(0) or order_request_rate_per_second: Some(0) in the config; or a malformed proxy_url reaching HttpClient::new.

Common situations: Setting rates to 0 intending 'unlimited'; config typos or defaults producing 0; explicitly disabling order rate limiting.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/6b0514c1bfd4da0f. Report an issue: GitHub.