nautechsystems/nautilus_trader · error · anyhow::Error

Binance Futures fill report range is incomplete: start {star

Error message

Binance Futures fill report range is incomplete: start {start} precedes complete-history boundary {complete_start}

What it means

Raised in generate_fill_reports when the requested start time precedes the 'complete-history boundary' (complete_start) computed by user_trades_complete_start from cmd.ts_init and the current clock. Binance userTrades lookups older than the retained complete-history window would silently return partial data, so the client refuses incomplete ranges instead of producing misleading fill reports.

Source

Thrown at crates/adapters/binance/src/futures/execution.rs:2467

        let symbol = format_binance_symbol(&instrument_id);
        let mut trades = Vec::new();
        let mut seen_trade_ids = AHashSet::new();
        let requested_end_time = cmd
            .end
            .map(|end| end.as_i64() / NANOSECONDS_IN_MILLISECOND as i64);

        if let Some(start) = cmd.start {
            let query_start_time = start.as_i64() / NANOSECONDS_IN_MILLISECOND as i64;
            let query_end_time = requested_end_time.unwrap_or_else(|| {
                self.clock.get_time_ns().as_i64() / NANOSECONDS_IN_MILLISECOND as i64
            });
            anyhow::ensure!(
                query_start_time <= query_end_time,
                "fill report start time must not exceed end time"
            );
            let complete_start = user_trades_complete_start(cmd.ts_init, self.clock.get_time_ns());
            anyhow::ensure!(
                start >= complete_start,
                "Binance Futures fill report range is incomplete: start {start} precedes complete-history boundary {complete_start}"
            );
            let mut window_start = query_start_time;

            loop {
                let window_end = window_start
                    .saturating_add(USER_TRADES_MAX_INTERVAL_MS)
                    .min(query_end_time);
                let mut from_id = None;

                loop {
                    let mut builder = BinanceUserTradesParamsBuilder::default();
                    builder.symbol(symbol.clone());
                    builder.limit(USER_TRADES_PAGE_LIMIT);

                    if let Some(cursor) = from_id {
                        builder.from_id(cursor);

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Move cmd.start forward to at least the complete-history boundary reported in the error message (complete_start).
  2. Fetch older fills directly from Binance (account export/older endpoints) instead of via this incomplete-range query.
  3. Check that cmd.ts_init is current; a stale ts_init inflates the boundary artificially.
  4. If you need the older data anyway, accept partial results by adjusting the adapter boundaries — only with full awareness of the correctness tradeoff.

Example fix

// before
let cmd = GenerateFillReports::new(None, old_start_ns, None); // old_start_ns < complete_start

// after
let complete_start = user_trades_complete_start(cmd_ts_init, clock.get_time_ns());
let start_ns = std::cmp::max(old_start_ns, complete_start);
let cmd = GenerateFillReports::new(None, start_ns, None);
Defensive patterns

Strategy: validation

Validate before calling

let complete_start = user_trades_complete_start(cmd_ts_init, clock.get_time_ns());
if start < complete_start {
    return Err(format!("clamp start to {complete_start} for complete history"));
}

Prevention

When it happens

Trigger: Requesting fill reports (via generate_mass_status) with a start timestamp earlier than the boundary the adapter derives for guaranteed-complete Binance user trade history — e.g. querying fills from before the account/data window the adapter can fully reconstruct.

Common situations: Backfilling very old fills for mass status, reconciling after long downtime where the requested window extends beyond complete history, or reusing a stale ts_init so the computed boundary is much later than expected.

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


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