nautechsystems/nautilus_trader · error · anyhow::Error

Failed to create HTTP client {i}: {e}

Error message

Failed to create HTTP client {i}: {e}

What it means

One of the BitMEX broadcast canceller's HTTP transport clients could not be constructed. During `new`, each configured transport builds an HTTP client (with retry, rate limits, recv window, proxy); a failure on client index `{i}` (invalid proxy URL, bad TLS backend config, etc.) is wrapped in this error.

Source

Thrown at crates/adapters/bitmex/src/broadcast/canceller.rs:403

                .proxy_urls
                .get(i)
                .and_then(|value| value.as_ref())
                .map(|value| value.expose_secret().to_owned());

            let client = BitmexHttpClient::with_credentials(
                config.api_key.clone().map(SecretString::into_inner),
                config.api_secret.clone().map(SecretString::into_inner),
                base_url.clone(),
                config.timeout_secs,
                config.max_retries,
                config.retry_delay_ms,
                config.retry_delay_max_ms,
                config.recv_window_ms,
                config.max_requests_per_second,
                config.max_requests_per_minute,
                proxy_url,
            )
            .map_err(|e| anyhow::anyhow!("Failed to create HTTP client {i}: {e}"))?;

            transports.push(TransportClient::new(client, format!("bitmex-cancel-{i}")));
        }

        Ok(Self {
            config,
            transports: Arc::from(transports),
            health_check_task: Arc::new(RwLock::new(None)),
            running: Arc::new(AtomicBool::new(false)),
            total_cancels: Arc::new(AtomicU64::new(0)),
            successful_cancels: Arc::new(AtomicU64::new(0)),
            failed_cancels: Arc::new(AtomicU64::new(0)),
            expected_rejects: Arc::new(AtomicU64::new(0)),
            idempotent_successes: Arc::new(AtomicU64::new(0)),
        })
    }

    /// Starts the broadcaster and health check loop.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the inner `{e}` message — it names the exact client-builder failure.
  2. Validate `proxy_url` in the BitMEX cancel config (must be a full URL like `http://host:port`).
  3. Ensure the CA/TLS environment is correct (e.g. set SSL_CERT_FILE / install ca-certificates in the container).
  4. Verify rate-limit and retry config values are sane positive integers.

Example fix

// before
proxy_url = Some("proxy.internal:8080".to_string());
// after
proxy_url = Some("http://proxy.internal:8080".to_string());
Defensive patterns

Strategy: try-catch

Validate before calling

fn validate_http_config(proxy_url: &Option<String>, max_rps: u32, max_rpm: u32) -> Result<(), String> {
    if let Some(url) = proxy_url {
        url::Url::parse(url).map_err(|e| format!("invalid proxy_url '{url}': {e}"))?;
    }
    if max_rps == 0 || max_rpm == 0 {
        return Err("rate limits must be > 0".into());
    }
    Ok(())
}

Try / catch

match HttpClient::new(...).map_err(|e| anyhow::anyhow!("Failed to create HTTP client {i}: {e}")) {
    Ok(client) => transports.push(TransportClient::new(client, name)),
    Err(e) => return Err(e.context("bitmex canceller init failed")),
}

Prevention

When it happens

Trigger: Instantiating the BitMEX broadcast canceller with `N` transports and transport `{i}`'s HTTP client builder fails — typically due to an invalid `proxy_url`, an unusable TLS/CA configuration, or an invalid rate-limit/retry parameter.

Common situations: Corporate proxy URL malformed or unreachable at startup; missing/invalid CA bundle in the container; bad config values (e.g. zero or negative max requests) rejected by the client builder.

Related errors


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