nautechsystems/nautilus_trader · error

invalid Binance Futures order-book depth; valid values are {

Error message

invalid Binance Futures order-book depth; valid values are {:?}

What it means

Thrown by BinanceFuturesHttpClient::request_book_snapshot when an explicit depth is supplied that is not one of Binance's allowed limits [5, 10, 20, 50, 100, 500, 1000] (crate::common::consts::BINANCE_BOOK_DEPTHS). The venue's depth endpoint only accepts those discrete limits, so the client validates before the request and the message enumerates the full valid set. Passing depth=None is fine — the venue picks a default.

Source

Thrown at crates/adapters/binance/src/futures/http/client.rs:3059

            .request_binance_bars(bar_type, start, end, limit)
            .await?
            .into_iter()
            .map(|bar| bar.bar())
            .collect())
    }

    /// Requests an explicit L2 order-book snapshot.
    ///
    /// # Errors
    ///
    /// Returns an error for an invalid depth, missing instrument, request failure, or invalid level.
    pub async fn request_book_snapshot(
        &self,
        instrument_id: InstrumentId,
        depth: Option<u32>,
    ) -> anyhow::Result<OrderBook> {
        if depth.is_some_and(|value| !crate::common::consts::BINANCE_BOOK_DEPTHS.contains(&value)) {
            anyhow::bail!(
                "invalid Binance Futures order-book depth; valid values are {:?}",
                crate::common::consts::BINANCE_BOOK_DEPTHS
            );
        }
        let (symbol, price_precision, size_precision) =
            self.cached_precisions_by_id(instrument_id)?;
        let params = BinanceDepthParams {
            symbol,
            limit: depth,
        };
        let snapshot = self.inner.depth(&params).await?;
        let ts_event = self.clock.get_time_ns();
        let sequence = u64::try_from(snapshot.last_update_id)
            .map_err(|_| anyhow::anyhow!("invalid negative order-book update ID"))?;
        let mut book = OrderBook::new(instrument_id, BookType::L2_MBP);
        for (index, level) in snapshot.bids.iter().enumerate() {
            let order = BookOrder::new(
                OrderSide::Buy,

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Pass None for the default, or clamp the requested depth up to the nearest allowed value in [5,10,20,50,100,500,1000]
  2. Validate depth against BINANCE_BOOK_DEPTHS at config load time with a clear error
  3. If you need exactly N levels, request the next larger valid depth and truncate the returned book client-side

Example fix

// before
let book = client.request_book_snapshot(instrument_id, Some(25)).await?;

// after
const VALID: [u32; 7] = [5, 10, 20, 50, 100, 500, 1000];
let depth = Some(25).map(|d| VALID.iter().copied().find(|&v| v >= d).unwrap_or(1000));
let book = client.request_book_snapshot(instrument_id, depth).await?;
Defensive patterns

Strategy: validation

Validate before calling

const VALID: [u32; 7] = [5, 10, 20, 50, 100, 500, 1000];
let depth = requested_depth.map(|d| {
    VALID.iter().copied().find(|&v| v >= d).unwrap_or(1000)
});
assert!(depth.is_none_or(|d| VALID.contains(&d)));

Type guard

fn is_valid_binance_depth(depth: u32) -> bool {
    [5, 10, 20, 50, 100, 500, 1000].contains(&depth)
}

Try / catch

On this bail, clamp the depth to the nearest allowed value (round up) and retry; None also works if the exact level count does not matter.

Prevention

When it happens

Trigger: Calling request_book_snapshot(instrument_id, Some(d)) with d like 25, 200, or 10000; UI knobs or config files exposing an unconstrained depth integer; copying depth values from another venue's adapter with different allowed sets.

Common situations: Config-driven order-book depth ('depth = 50' works, 'depth = 25' fails); porting spot-vs-futures assumptions where valid sets differ; truncating a user-requested N-level view directly into the venue depth parameter instead of fetching a valid superset and trimming.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/b562ed2294b21c53. Report an issue: GitHub.