nautechsystems/nautilus_trader · error

BinanceFuturesDataClient requires UsdM or CoinM product…

Error message

BinanceFuturesDataClient requires UsdM or CoinM product type, was {product_type:?}

What it means

BinanceFuturesDataClient::new asserts that the configured BinanceProductType is UsdM or CoinM after validating the config. Any other product type (e.g. Spot) cannot be served by the futures data client and construction fails with this error.

Solutions

  1. Pass BinanceProductType::UsdM or BinanceProductType::CoinM when constructing the futures data client
  2. Use the spot data client for Spot product type instead of the futures client
  3. Prefer the client factory, which routes product types to the correct client implementation

Example fix

// before
let client = BinanceFuturesDataClient::new(client_id, config, BinanceProductType::Spot)?;
// after
let client = BinanceFuturesDataClient::new(client_id, config, BinanceProductType::UsdM)?;
Defensive patterns

Strategy: validation

Validate before calling

fn assert_futures_product(pt: BinanceProductType) -> Result<(), String> {
    match pt {
        BinanceProductType::UsdM | BinanceProductType::CoinM => Ok(()),
        other => Err(format!("futures client requires UsdM/CoinM, got {other:?}")),
    }
}

Type guard

fn is_futures_product(pt: BinanceProductType) -> bool {
    matches!(pt, BinanceProductType::UsdM | BinanceProductType::CoinM)
}

Try / catch

match BinanceFuturesDataClient::new(client_id, config, product_type) {
    Err(e) if e.to_string().contains("requires UsdM or CoinM") => {
        eprintln!("Use the spot data client for Spot product type: {e}");
    }
    r => r?,
}

Prevention

When it happens

Trigger: Directly constructing BinanceFuturesDataClient::new(client_id, config, product_type) with product_type = Spot or another non-futures variant.

Common situations: Wiring a Binance data client manually (not via the factory) and passing the wrong product type; a config that says futures but the enum resolved to Spot; copy-pasted client construction code from a spot example.

Related errors


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

Appendix: source

Thrown at crates/adapters/binance/src/futures/data.rs:166

impl BinanceFuturesDataClient {
    /// Creates a new [`BinanceFuturesDataClient`] instance.
    ///
    /// # Errors
    ///
    /// Returns an error if the client fails to initialize or if the product type
    /// is not a futures type (UsdM or CoinM).
    pub fn new(
        client_id: ClientId,
        config: BinanceDataClientConfig,
        product_type: BinanceProductType,
    ) -> anyhow::Result<Self> {
        config.validate()?;

        match product_type {
            BinanceProductType::UsdM | BinanceProductType::CoinM => {}
            _ => {
                anyhow::bail!(
                    "BinanceFuturesDataClient requires UsdM or CoinM product type, was {product_type:?}"
                );
            }
        }

        let clock = get_atomic_clock_realtime();
        let data_sender = get_data_event_sender();
        let socket_factory = SocketControlFactory::new(client_id, Some(*BINANCE_VENUE));
        let api_key = config
            .api_key
            .as_ref()
            .map(|value| value.expose_secret().to_owned());
        let api_secret = config
            .api_secret
            .as_ref()
            .map(|value| value.expose_secret().to_owned());
        let proxy_url = config
            .proxy_url

View on GitHub (pinned to 18893faf8b)