nautechsystems/nautilus_trader · error

Bybit only supports L2_MBP order book deltas

Error message

Bybit only supports L2_MBP order book deltas

What it means

The Bybit adapter only implements L2 market-by-price (L2_MBP) order book delta subscriptions. subscribe_book_deltas rejects any other BookType (e.g. L3_MBO) up front because the exchange does not provide that data model and the adapter has no mapping for it.

Source

Thrown at crates/adapters/bybit/src/data.rs:1016

        if self.shutdown_errors.is_empty() {
            Ok(())
        } else {
            let errors = std::mem::take(&mut self.shutdown_errors);
            anyhow::bail!("Bybit data shutdown failed: {}", errors.join("; "))
        }
    }

    fn is_connected(&self) -> bool {
        self.is_connected.load(Ordering::Relaxed)
    }

    fn is_disconnected(&self) -> bool {
        !self.is_connected()
    }

    fn subscribe_book_deltas(&mut self, cmd: SubscribeBookDeltas) -> anyhow::Result<()> {
        if cmd.book_type != BookType::L2_MBP {
            anyhow::bail!("Bybit only supports L2_MBP order book deltas");
        }

        let depth = cmd
            .depth
            .map_or(BYBIT_DEFAULT_ORDERBOOK_DEPTH, |d| d.get() as u32);

        validate_orderbook_depth(depth)?;

        let instrument_id = cmd.instrument_id;
        let product_type = self
            .get_product_type_for_instrument(instrument_id)
            .unwrap_or(BybitProductType::Linear);

        let ws = self
            .get_ws_client_for_product(product_type)
            .context("no WebSocket client for product type")?
            .clone();

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Change the subscription to BookType::L2_MBP in your data config/command
  2. If you need L3 data, use a venue that supports it; Bybit does not provide it
  3. Verify the BookType in your strategy's data requests before dispatching to the Bybit client

Example fix

// before
let cmd = SubscribeBookDeltas { book_type: BookType::L3_MBO, .. };
// after
let cmd = SubscribeBookDeltas { book_type: BookType::L2_MBP, .. };
Defensive patterns

Strategy: validation

Validate before calling

if cmd.book_type != BookType::L2_MBP {
    return Err(anyhow::anyhow!("Bybit requires L2_MBP; got {:?}", cmd.book_type));
}

Try / catch

match client.subscribe_book_deltas(cmd) {
    Err(e) if e.to_string().contains("L2_MBP") => {
        log::warn!("coercing book type to L2_MBP for Bybit");
        client.subscribe_book_deltas(set_book_type(cmd, BookType::L2_MBP))?;
    }
    r => r?,
}

Prevention

When it happens

Trigger: Issuing a SubscribeBookDeltas command with cmd.book_type set to something other than BookType::L2_MBP — e.g. configuring L3_MBO book types from another venue's config.

Common situations: Reusing a data client config built for venues supporting L3 data; a strategy data spec defaulting to a different book type; copy-pasted subscription code across adapters.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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