nautechsystems/nautilus_trader · error · anyhow::Error

cannot subscribe L1_MBP and L2_MBP for the same Binance…

Error message

cannot subscribe L1_MBP and L2_MBP for the same Binance Futures instrument

What it means

Binance Futures cannot mix an L1_MBP (book-ticker) subscription with an L2_MBP (depth) subscription for the same instrument. When subscribing L1, the handler checks book_subscriptions (L2 refs) and fails if the instrument already has an L2 subscription; the mirror check exists on the L2 path.

Solutions

  1. Unsubscribe the existing L2_MBP subscription before requesting L1_MBP for that instrument
  2. Standardize one book type per instrument across all strategies in the node
  3. Use separate client instances if genuinely independent book views per strategy are needed

Example fix

// before
subscribe_book(L2_MBP, "BTCUSDT-PERP.BINANCE");
subscribe_book(L1_MBP, "BTCUSDT-PERP.BINANCE"); // panics/errors
// after
unsubscribe_book(L2_MBP, "BTCUSDT-PERP.BINANCE");
subscribe_book(L1_MBP, "BTCUSDT-PERP.BINANCE");
Defensive patterns

Strategy: validation

Validate before calling

fn can_subscribe_l1(instrument_id: InstrumentId, l2_subs: &HashMap<InstrumentId, usize>) -> bool {
    !l2_subs.contains_key(&instrument_id)
}

Try / catch

if let Err(e) = client.subscribe_book_deltas(cmd) {
    if e.to_string().contains("L1_MBP and L2_MBP for the same") {
        log::warn!("book type conflict for {}; unsubscribing existing first", cmd.instrument_id);
        client.unsubscribe_book_deltas(opposite(cmd))?;
        client.subscribe_book_deltas(cmd)?;
    } else { return Err(e.into()); }
}

Prevention

When it happens

Trigger: Subscribing L1_MBP for an instrument that already has an active L2_MBP subscription (or vice versa) via SubscribeBookDeltas on Binance Futures.

Common situations: Two strategies in one node subscribing different book depths for the same symbol; a strategy falling back from L2 to L1 without unsubscribing first; shared subscription manager re-adding a cheaper top-of-book feed alongside the depth feed.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

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

            "subscribe_instruments: Binance Futures instruments are fetched via HTTP on connect"
        );
        Ok(())
    }

    fn subscribe_instrument(&mut self, _cmd: SubscribeInstrument) -> anyhow::Result<()> {
        log::debug!(
            "subscribe_instrument: Binance Futures instruments are fetched via HTTP on connect"
        );
        Ok(())
    }

    fn subscribe_book_deltas(&mut self, cmd: SubscribeBookDeltas) -> anyhow::Result<()> {
        if cmd.book_type == BookType::L1_MBP {
            anyhow::ensure!(
                cmd.depth.is_none_or(|depth| depth.get() == 1),
                "Binance Futures L1_MBP supports depth 1 only"
            );
            anyhow::ensure!(
                !self.book_subscriptions.contains_key(&cmd.instrument_id),
                "cannot subscribe L1_MBP and L2_MBP for the same Binance Futures instrument"
            );
            self.l1_book_subscriptions.rcu(|subscriptions| {
                *subscriptions.entry(cmd.instrument_id).or_insert(0) += 1;
            });
            self.subscribe_top_of_book(cmd.instrument_id);
            return Ok(());
        }

        if cmd.book_type != BookType::L2_MBP {
            anyhow::bail!("Binance Futures supports L1_MBP and L2_MBP order book subscriptions");
        }
        anyhow::ensure!(
            !self.l1_book_subscriptions.contains_key(&cmd.instrument_id),
            "cannot subscribe L1_MBP and L2_MBP for the same Binance Futures instrument"
        );

View on GitHub (pinned to 18893faf8b)