nautechsystems/nautilus_trader · error

Lighter only supports L2_MBP order book {label}

Error message

Lighter only supports L2_MBP order book {label}

What it means

Lighter order book data only supports the L2_MBP (level-2 market-by-price) BookType. The helper validate_l2_mbp_book_type, called from validate_book_deltas_subscription and validate_book_depth10_subscription, rejects any other book type (e.g. L3_MBO) with this message; {label} indicates which subscription kind (deltas or depth10) was requested.

Source

Thrown at crates/adapters/lighter/src/data/mod.rs:1846

    end_nanos: Option<UnixNanos>,
) -> bool {
    start_nanos.is_none_or(|start| ts_event >= start) && end_nanos.is_none_or(|end| ts_event <= end)
}

/// Returns an error if `book_type` is not [`BookType::L2_MBP`].
///
/// Lighter publishes only level-aggregated book updates, so any other book
/// type cannot be served by the WebSocket feed.
fn validate_book_deltas_subscription(book_type: BookType) -> anyhow::Result<()> {
    validate_l2_mbp_book_type(book_type, "deltas")
}

fn validate_book_depth10_subscription(book_type: BookType) -> anyhow::Result<()> {
    validate_l2_mbp_book_type(book_type, "depth10")
}

fn validate_l2_mbp_book_type(book_type: BookType, label: &str) -> anyhow::Result<()> {
    anyhow::ensure!(
        book_type == BookType::L2_MBP,
        "Lighter only supports L2_MBP order book {label}",
    );
    Ok(())
}

#[cfg(test)]
mod tests {
    use std::{num::NonZeroUsize, time::Duration};

    use axum::{
        Router,
        extract::Query,
        http::StatusCode,
        response::{IntoResponse, Response},
        routing::get,
    };
    use jiff::Timestamp;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set the order book subscription's BookType to BookType::L2_MBP.
  2. If you need L3/MBO granularity, use a different venue that supports it.
  3. Check the data type in your subscribe/config payload for typos or wrong defaults.
  4. For depth10, keep BookType::L2_MBP — only the label differs, the requirement is the same.

Example fix

// before
OrderBookSub(Entry::new(instrument_id, BookType::L3_MBO))
// after
OrderBookSub(Entry::new(instrument_id, BookType::L2_MBP))
Defensive patterns

Strategy: validation

Validate before calling

if book_type != BookType::L2_MBP {
    return Err(anyhow!("Lighter requires BookType::L2_MBP for book subscriptions"));
}

Try / catch

match client.subscribe_book_deltas(sub) {
    Err(e) if e.to_string().contains("only supports L2_MBP") => {
        // re-subscribe with BookType::L2_MBP
    }
    r => r?,
}

Prevention

When it happens

Trigger: Subscribing to book deltas or depth10 with a BookType other than BookType::L2_MBP in the subscription's data type.

Common situations: Configuring an L3/order-book-ticks book type copied from another venue adapter; a default book type in a generic config that isn't L2_MBP.

Related errors


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