nautechsystems/nautilus_trader · error

unsupported Binance instrument filter {key:?} for {product_t

Error message

unsupported Binance instrument filter {key:?} for {product_type:?}

What it means

BinanceDataClientConfig.validate accepts only the instrument filter keys 'symbols', 'bases' and 'quotes', plus 'contract_types' when product_type is UsdM or CoinM. Any other key (or contract_types on Spot/Margin/Options) fails validation because the v2 provider has no code path to apply it.

Source

Thrown at crates/adapters/binance/src/config.rs:112

        if let Some(load_ids) = &self.load_ids {
            for raw in load_ids {
                let instrument_id = InstrumentId::from_str(raw)
                    .map_err(|e| anyhow::anyhow!("invalid Binance load_ids value {raw:?}: {e}"))?;
                anyhow::ensure!(
                    instrument_id.venue.as_str() == "BINANCE",
                    "Binance load_ids value {raw:?} must use venue BINANCE"
                );
            }
        }

        for (key, value) in &self.filters {
            let supported = matches!(key.as_str(), "symbols" | "bases" | "quotes")
                || key == "contract_types"
                    && matches!(
                        product_type,
                        BinanceProductType::UsdM | BinanceProductType::CoinM
                    );
            anyhow::ensure!(
                supported,
                "unsupported Binance instrument filter {key:?} for {product_type:?}"
            );
            validate_filter_strings(key, value)?;
        }

        Ok(())
    }
}

fn validate_filter_strings(name: &str, value: &serde_json::Value) -> anyhow::Result<()> {
    let valid = match value {
        serde_json::Value::String(value) => !value.trim().is_empty(),
        serde_json::Value::Array(values) => {
            !values.is_empty()
                && values
                    .iter()
                    .all(|value| value.as_str().is_some_and(|value| !value.trim().is_empty()))

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Rename unsupported keys to the supported ones: symbols (exact symbols), bases (base assets), quotes (quote assets).
  2. Only use contract_types with BinanceProductType::UsdM or CoinM; remove it from Spot configs.
  3. Run config.validate() right after building the config so the failure surfaces before node start.

Example fix

# before (Spot config with futures-only filter)
BinanceDataClientConfig(
    product_type='SPOT',
    instrument_provider=BinanceFuturesInstrumentProviderConfig(
        filters={'contract_types': ['PERPETUAL']},
    ),
)

# after
BinanceDataClientConfig(
    product_type='SPOT',
    instrument_provider=BinanceFuturesInstrumentProviderConfig(
        filters={'quotes': ['USDT']},
    ),
)
Defensive patterns

Strategy: validation

Validate before calling

BASE_KEYS = {'symbols', 'bases', 'quotes'}

def filters_supported(filters: dict, product_type: str) -> bool:
    for k in filters:
        if k in BASE_KEYS:
            continue
        if k == 'contract_types' and product_type in ('USD_M', 'COIN_M'):
            continue
        return False
    return True

assert filters_supported(cfg_filters, product_type)

Try / catch

try:
    config.validate()
except Exception as e:
    raise SystemExit(f'Binance filter config invalid: {e}')

Prevention

When it happens

Trigger: Passing filters={'assets': ['USDT']} or {'pairs': [...]} to the instrument provider config; using filters={'contract_types': ['PERPETUAL']} together with product_type='SPOT' (contract types only exist on futures venues).

Common situations: Copy-pasting filter dictionaries from other adapters (Bybit/OKX use different key names); old legacy-adapter configs whose filter names did not carry over to v2; assuming Spot supports contract_types because the key exists in the config schema.

Related errors


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