nautechsystems/nautilus_trader · error

Data config start_time ({start}) must be <= end_time ({end})

Error message

Data config start_time ({start}) must be <= end_time ({end})

What it means

validate_configs found a data config whose start_time is later than its end_time; an inverted time range would request negative-duration data, so the node rejects the configuration before building engines.

Source

Thrown at crates/backtest/src/node.rs:336

    let mut seen_ids = AHashSet::new();

    for config in configs {
        anyhow::ensure!(
            seen_ids.insert(config.id()),
            "Duplicate run config ID '{}'",
            config.id()
        );

        let venue_names: Vec<String> = config
            .venues()
            .iter()
            .map(|v| v.name().to_string())
            .collect();

        for data_config in config.data() {
            if let (Some(start), Some(end)) = (data_config.start_time(), data_config.end_time()) {
                anyhow::ensure!(
                    start <= end,
                    "Data config start_time ({start}) must be <= end_time ({end})"
                );
            }

            for instrument_id in data_config.get_instrument_ids()? {
                let venue = instrument_id.venue.to_string();
                anyhow::ensure!(
                    venue_names.contains(&venue),
                    "No venue config found for venue '{venue}' (required by instrument {instrument_id})"
                );
            }
        }

        for venue_config in config.venues() {
            let needs_book_data = matches!(
                venue_config.book_type(),
                BookType::L2_MBP | BookType::L3_MBO

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Swap the values so start_time <= end_time in the data config
  2. Fix the code computing the range (argument order, timezone, unit confusion)
  3. Validate user-supplied date ranges before constructing BacktestDataConfig

Example fix

// before
BacktestDataConfig::new(..., start_time: end.into(), end_time: start.into())
// after
assert!(start <= end);
BacktestDataConfig::new(..., start_time: start.into(), end_time: end.into())
Defensive patterns

Strategy: validation

Validate before calling

if let (Some(s), Some(e)) = (data_config.start_time(), data_config.end_time()) {
    assert!(s <= e, "start_time {s} after end_time {e}");
}

Prevention

When it happens

Trigger: A BacktestDataConfig whose start_time is strictly after its end_time, passed via BacktestRunConfig to `BacktestNode::new` — e.g. swapped arguments or a computed range that resolved backwards.

Common situations: Swapped start/end arguments; computing dates relative to 'now' where timezone or ordering bugs inverted the interval; user-supplied date ranges from a UI or CLI in conflicting order or formats.

Related errors


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