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
- Unsubscribe the existing L2_MBP subscription before requesting L1_MBP for that instrument
- Standardize one book type per instrument across all strategies in the node
- 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
- Track active book subscriptions per instrument in your strategy layer
- Enforce one book type per instrument in the subscription manager
- Unsubscribe before switching book depth types
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
- Lighter only supports L2_MBP order book
- Binance Futures L1_MBP supports depth 1 only
- Binance Futures supports L1_MBP and L2_MBP order book…
- Binance Spot L1_MBP supports depth 1 only
- BitMEX only supports L2_MBP order book deltas
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)