nautechsystems/nautilus_trader · error

Derive only supports L2_MBP order book deltas

Error message

Derive only supports L2_MBP order book deltas

What it means

Raised by `subscribe_book_deltas` when the requested order book type is not `BookType::L2_MBP`. Derive's WebSocket order book feed only provides level-2 market-by-price data, so other book types (e.g. L3_MBO) are rejected up front.

Source

Thrown at crates/adapters/derive/src/data.rs:803

        self.is_connected.store(true, Ordering::Release);
        setup_guard.disarm();
        log::info!(
            "Connected Derive data client ({:?})",
            self.config.environment
        );
        Ok(())
    }

    async fn disconnect(&mut self) -> anyhow::Result<()> {
        self.teardown_partial_connect().await?;
        log::info!("Disconnected Derive data client");
        Ok(())
    }

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

        let instrument_id = cmd.instrument_id;
        let owner = ChannelOwner::BookDeltas(instrument_id);
        let lifecycle = self.subscription_lifecycle();
        if lifecycle.is_active(owner) {
            return Ok(());
        }

        let instrument_name = format_venue_symbol(&instrument_id)?.to_string();
        let group = orderbook_group(&cmd.params)?;
        let depth = orderbook_depth(cmd.depth.map(|d| d.get()), &cmd.params)?;
        let channel = orderbook_channel(&instrument_name, &group, &depth);
        let request = ChannelRequest::from_channel(&channel)?;
        let needs_load = self.prepare_subscribe(instrument_id)?;
        let Some(generation) = lifecycle.activate(owner, Some(&channel)) else {
            return Ok(());
        };

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Change the subscription command to use BookType::L2_MBP.
  2. If L3/MBO granularity is required, use a different adapter/venue that supports it.
  3. Validate the book_type in your strategy config before subscribing.

Example fix

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

Strategy: validation

Validate before calling

assert!(matches!(cmd.book_type, BookType::L2_MBP), "Derive book deltas require L2_MBP");

Try / catch

if cmd.book_type != BookType::L2_MBP {
    log::warn!("coercing book_type to L2_MBP for Derive");
    cmd.book_type = BookType::L2_MBP;
}

Prevention

When it happens

Trigger: Issuing a SubscribeBookDeltas command with `book_type` set to anything other than L2_MBP (e.g. L1_MBP or L3_MBO) against the Derive data client.

Common situations: Reusing subscription code written for venues supporting L3/MBO data; strategy configs specifying a deeper or aggregated book type; copy-pasted subscribe calls 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/6c793a1cf980a480. Report an issue: GitHub.