nautechsystems/nautilus_trader · error
invalid negative order-book update ID
Error message
invalid negative order-book update ID
What it means
Thrown in `parse_book_snapshot_response` when the depth snapshot's `last_update_id` is negative and cannot be converted to the unsigned `u64` sequence number required by NautilusTrader's `OrderBook`. Binance should never send a negative update ID, so this is a defensive invariant check against malformed API responses.
Source
Thrown at crates/adapters/binance/src/spot/http/client.rs:3064
}
let instrument = self.instrument_from_cache_by_id(instrument_id)?;
let params = DepthParams {
symbol: instrument_id.symbol.to_string(),
limit: depth,
};
let snapshot = self.inner.depth(¶ms).await?;
let ts_event = self.generate_ts_init();
Self::parse_book_snapshot_response(instrument_id, &instrument, &snapshot, ts_event)
}
fn parse_book_snapshot_response(
instrument_id: InstrumentId,
instrument: &InstrumentAny,
snapshot: &BinanceDepth,
ts_event: UnixNanos,
) -> anyhow::Result<OrderBook> {
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);
let mut add_level = |level: &super::models::BinancePriceLevel,
side: OrderSide,
order_id: usize,
name: &str|
-> anyhow::Result<()> {
let price = Price::from_mantissa_exponent_checked(
level.price_mantissa,
snapshot.price_exponent,
instrument.price_precision(),
)
.map_err(|e| anyhow::anyhow!("invalid {name} price: {e}"))?;
anyhow::ensure!(price.is_positive(), "invalid non-positive {name} price");
let qty_mantissa = u64::try_from(level.qty_mantissa)
.map_err(|_| anyhow::anyhow!("invalid negative {name} quantity"))?;
let quantity = Quantity::from_mantissa_exponent_checked(
qty_mantissa,
snapshot.qty_exponent,View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the raw depth response to confirm `lastUpdateId` is a non-negative integer.
- Re-fetch the snapshot; a single malformed response is usually transient.
- If using a proxy/mock, fix the fixture to emit valid non-negative update IDs.
- Report a bug if a genuine Binance response contains a negative ID.
Example fix
// before: snapshot from an untrusted source used directly
let book = client.request_book_snapshot(instrument_id, Some(5000)).await?;
// after: retry on malformed snapshots
let book = match client.request_book_snapshot(instrument_id, Some(5000)).await {
Ok(b) => b,
Err(e) if e.to_string().contains("invalid negative order-book update ID") => {
client.request_book_snapshot(instrument_id, Some(5000)).await?
}
Err(e) => return Err(e),
}; Defensive patterns
Strategy: validation
Validate before calling
fn has_valid_update_id(snapshot: &BinanceDepth) -> bool { snapshot.last_update_id >= 0 } Type guard
fn valid_snapshot(s: &BinanceDepth) -> bool { s.last_update_id >= 0 && !s.bids.is_empty() && !s.asks.is_empty() } Try / catch
match client.request_book_snapshot(id, depth).await {
Ok(book) => book,
Err(e) if e.to_string().contains("invalid negative order-book update ID") => retry_snapshot(id, depth).await?,
Err(e) => return Err(e),
} Prevention
- Re-fetch snapshots on parse errors rather than propagating stale data.
- Avoid routing exchange traffic through proxies that rewrite payloads.
- Validate fixtures/mocks emit non-negative lastUpdateId.
When it happens
Trigger: Calling `request_book_snapshot` when the Binance `/api/v3/depth` response contains a negative `lastUpdateId` — essentially only possible with a corrupted, mocked, or non-conformant response payload.
Common situations: Proxy or MITM tooling returning synthesized/garbage depth JSON; a test fixture or mock server with negative IDs; a breaking change in the upstream API response schema.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Binance Spot order-book depth must be between 1 and 5000
- Binance Spot L1_MBP supports depth 1 only
- invalid {name} price: {e}
- invalid non-positive {name} price
- invalid negative {name} quantity
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/cf8dbb111dacf50a.
Report an issue: GitHub.