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
- Change the subscription command to use BookType::L2_MBP.
- If L3/MBO granularity is required, use a different adapter/venue that supports it.
- 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
- Constrain book subscriptions to L2_MBP for Derive in strategy configs.
- Centralize venue capability checks in one place before subscribing.
- Fall back to trades/ticker feeds when L3 data is needed but unsupported.
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
- Derive only supports L2_MBP order book depth
- Binance Futures supports L1_MBP and L2_MBP order book subscr
- BitMEX only supports L2_MBP order book deltas
- Deribit only supports L2_MBP order book deltas
- Deribit only supports L2_MBP order book depth
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/6c793a1cf980a480.
Report an issue: GitHub.