nautechsystems/nautilus_trader · error

Binance Spot kline subscriptions require JSON market-data…

Error message

Binance Spot kline subscriptions require JSON market-data mode

What it means

Bar (kline) subscriptions on Binance Spot are only available in JSON market-data mode, because kline streams are delivered via the public JSON WebSocket. The client rejects subscribe_bars when running in SBE mode.

Solutions

  1. Set the Spot data client market-data mode to BinanceSpotMarketDataMode::Json in the adapter config.
  2. Alternatively obtain bars via internal aggregation (subscribe quotes/trades and let the engine aggregate) instead of external kline streams.
  3. Verify the mode before building strategies that need klines.

Example fix

// before
config.spot_market_data_mode = BinanceSpotMarketDataMode::Sbe;
// after
config.spot_market_data_mode = BinanceSpotMarketDataMode::Json; // required for kline subscriptions
Defensive patterns

Strategy: validation

Validate before calling

fn bars_require_json_mode(mode: BinanceSpotMarketDataMode) -> Result<(), String> {
    if mode == BinanceSpotMarketDataMode::Json { Ok(()) } else { Err("klines require JSON market-data mode".into()) }
}

Try / catch

match client.subscribe_bars(cmd) {
    Err(e) if e.to_string().contains("require JSON market-data mode") => {
        log::warn!("restart adapter in JSON mode or aggregate bars internally");
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling subscribe_bars while spot_market_data_mode == Sbe, e.g. the adapter was configured with SBE market data and a strategy requests bar subscriptions.

Common situations: Running an SBE-configured data client and adding a bar-based strategy; defaults to SBE mode in config while strategy needs klines; switching data types without revisiting mode config.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at crates/adapters/binance/src/spot/data.rs:1974

    fn subscribe_trades(&mut self, cmd: SubscribeTrades) -> anyhow::Result<()> {
        let instrument_id = cmd.instrument_id;
        let ws = self.ws_client.clone();

        let stream = format!("{}@trade", instrument_id.symbol.as_str().to_lowercase());

        self.spawn_ws(
            async move {
                ws.subscribe(vec![stream])
                    .await
                    .context("trades subscription")
            },
            "trade subscription",
        );
        Ok(())
    }

    fn subscribe_bars(&mut self, cmd: SubscribeBars) -> anyhow::Result<()> {
        anyhow::ensure!(
            self.spot_market_data_mode == BinanceSpotMarketDataMode::Json,
            "Binance Spot kline subscriptions require JSON market-data mode"
        );
        let bar_type = cmd.bar_type;
        let ws = self.ws_client.clone();
        let interval = bar_spec_to_binance_interval(bar_type.spec())?;

        let stream = format!(
            "{}@kline_{}",
            bar_type.instrument_id().symbol.as_str().to_lowercase(),
            interval.as_str()
        );

        self.spawn_ws(
            async move {
                ws.subscribe(vec![stream])
                    .await
                    .context("bars subscription")

View on GitHub (pinned to 18893faf8b)