nautechsystems/nautilus_trader · error

Unsupported bar aggregation for Binance: {agg:?}

Error message

Unsupported bar aggregation for Binance: {agg:?}

What it means

Thrown by bar_spec_to_binance_interval when the BarSpecification's aggregation method is not one Binance klines can represent. Binance only serves time-based klines (Second, Minute, Hour, Day, Week, Month with fixed steps), so non-time aggregations such as TICK, VOLUME, DOLLAR, VALUE, or sub-second units cannot be mapped and the conversion fails fast.

Source

Thrown at crates/adapters/binance/src/common/parse.rs:1469

            6 => BinanceKlineInterval::Hour6,
            8 => BinanceKlineInterval::Hour8,
            12 => BinanceKlineInterval::Hour12,
            _ => anyhow::bail!("Unsupported hour interval: {step}h"),
        },
        BarAggregation::Day => match step {
            1 => BinanceKlineInterval::Day1,
            3 => BinanceKlineInterval::Day3,
            _ => anyhow::bail!("Unsupported day interval: {step}d"),
        },
        BarAggregation::Week => match step {
            1 => BinanceKlineInterval::Week1,
            _ => anyhow::bail!("Unsupported week interval: {step}w"),
        },
        BarAggregation::Month => match step {
            1 => BinanceKlineInterval::Month1,
            _ => anyhow::bail!("Unsupported month interval: {step}M"),
        },
        agg => anyhow::bail!("Unsupported bar aggregation for Binance: {agg:?}"),
    };

    Ok(interval)
}

pub(crate) fn quote_to_l1_deltas(quote: QuoteTick, sequence: u64) -> OrderBookDeltas {
    let bid_action = if quote.bid_size.is_zero() {
        BookAction::Delete
    } else {
        BookAction::Update
    };
    let ask_action = if quote.ask_size.is_zero() {
        BookAction::Delete
    } else {
        BookAction::Update
    };
    let bid = OrderBookDelta::new(
        quote.instrument_id,

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Switch to a time-based aggregation Binance supports, e.g. '1-SECOND-LAST-INTERNAL' or '1-MINUTE-LAST-INTERNAL'.
  2. For TICK/VOLUME/DOLLAR bars, subscribe to the exchange's trade/quote/ticker streams and build the bars yourself (custom data engine or an Actor that aggregates).
  3. Validate every BarType against the supported set in bar_spec_to_binance_interval before starting the node.

Example fix

# before
bar_type = BarType.from_str('BTCUSDT.BINANCE-100-TICK-LAST-INTERNAL')

# after (aggregate locally from trades if you need tick bars)
bar_type = BarType.from_str('BTCUSDT.BINANCE-1-SECOND-LAST-INTERNAL')
client.subscribe_bars(BarSubscription(bar_type))
Defensive patterns

Strategy: validation

Validate before calling

TIME_BASED = ('SECOND', 'MINUTE', 'HOUR', 'DAY', 'WEEK', 'MONTH')

def is_time_based(bar_spec) -> bool:
    return bar_spec.aggregation_string in TIME_BASED

assert is_time_based(bar_type.spec), 'Binance klines require time-based aggregation'

Type guard

def supports_binance_klines(bar_type) -> bool:
    return bar_type.spec.aggregation_string in (
        'SECOND', 'MINUTE', 'HOUR', 'DAY', 'WEEK', 'MONTH'
    )

Prevention

When it happens

Trigger: Subscribing to or requesting bars with a BarType like 'BTCUSDT.BINANCE-100-TICK-LAST-INTERNAL', '-5000-DOLLAR-', '-100-VOLUME-', or '-1-MILLISECOND-' through the Binance data client; the same path is hit by request_bars for historical data.

Common situations: Strategies written against the backtest engine or venues that synthesize tick/dollar/volume bars, then pointed at the live Binance adapter; copying a BarType string from a different adapter's docs; sub-second bars expected because Nautilus supports them in backtests.

Related errors


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