nautechsystems/nautilus_trader · error
invalid Futures kline {}: {e}
Error message
invalid Futures kline {}: {e} What it means
Thrown by parse_futures_kline_binance_bar when a kline's open/high price field cannot be parsed into a Price at the instrument's price_precision. Each of open/high/low/close (and volume) is wrapped with the same message keyed by kline.open_time, so this specific instance fires when the OHLC parse fails on one of the first fields; the underlying error is either a malformed decimal string or a value whose precision exceeds the cached instrument's price_precision.
Source
Thrown at crates/adapters/binance/src/futures/http/client.rs:3212
};
parse_futures_trade_tick(
&trade,
instrument_id,
price_precision,
size_precision,
ts_init,
)
}
fn parse_futures_kline_binance_bar(
kline: &BinanceFuturesKline,
bar_type: BarType,
price_precision: u8,
size_precision: u8,
ts_init: UnixNanos,
) -> anyhow::Result<BinanceBar> {
let open = parse_required_price_at_precision(&kline.open, price_precision, "kline.open")
.map_err(|e| anyhow::anyhow!("invalid Futures kline {}: {e}", kline.open_time))?;
let high = parse_required_price_at_precision(&kline.high, price_precision, "kline.high")
.map_err(|e| anyhow::anyhow!("invalid Futures kline {}: {e}", kline.open_time))?;
let low = parse_required_price_at_precision(&kline.low, price_precision, "kline.low")
.map_err(|e| anyhow::anyhow!("invalid Futures kline {}: {e}", kline.open_time))?;
let close = parse_required_price_at_precision(&kline.close, price_precision, "kline.close")
.map_err(|e| anyhow::anyhow!("invalid Futures kline {}: {e}", kline.open_time))?;
let volume =
parse_required_quantity_at_precision(&kline.volume, size_precision, "kline.volume")
.map_err(|e| anyhow::anyhow!("invalid Futures kline {}: {e}", kline.open_time))?;
let ts_event = parse_millis(kline.close_time, "Futures kline close time")?;
let quote_volume = kline.quote_volume.parse::<Decimal>().map_err(|e| {
anyhow::anyhow!(
"invalid Futures kline {} quote volume: {e}",
kline.open_time
)
})?;
let taker_buy_base_volume = klineView on GitHub (pinned to a4b06ed870)
Solutions
- Reload instrument definitions to pick up current price_precision, then retry the kline request
- Log the failing kline's open_time and compare the raw JSON decimals against the cached precision
- Use raw venue exchangeInfo to confirm whether PRICE_FILTER tickSize changed for the symbol
- In tests, generate fixtures with prices consistent with the instrument precision used to seed the cache
Defensive patterns
Strategy: validation
Validate before calling
// ensure cache precision matches live metadata before backfill client.request_instruments(None).await?; // refresh before long backfills let (symbol, pp, sp) = client.cached_precisions_by_id(instrument_id)?;
Try / catch
Catch with the kline open_time from the message; log the raw kline, refresh the instrument cache once, and retry the request window; abort the backfill if mismatches persist.
Prevention
- Refresh instruments at the start of backfill jobs
- Generate kline fixtures at the seeded instrument's precision
- Watch exchangeInfo for PRICE_FILTER tickSize changes on held symbols
When it happens
Trigger: Kline payloads (request_binance_bars / historical klines) with more price decimals than the cached instrument declares — classic stale-instrument-cache drift after Binance tick-size changes; malformed strings from fixtures or proxies; negative/zero prices that Price rejects.
Common situations: Historical backfill jobs running long after session start against a stale instrument cache; testnet/mainnet metadata divergence; hand-built kline fixtures in tests with arbitrary precision; schema drift after Binance API updates.
Related errors
- invalid Futures trade id {}: {e}
- Instrument not found in cache: {symbol}
- Only EXTERNAL aggregation is supported
- Binance Futures does not support second-level kline interval
- Binance Futures does not support {a:?} aggregation
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/939c5a990d457f10.
Report an issue: GitHub.