nautechsystems/nautilus_trader · error
Binance Futures does not support second-level kline interval
Error message
Binance Futures does not support second-level kline intervals
What it means
Binance futures kline streams and endpoints have no 1-second interval (unlike Binance spot, which added one), so `subscribe_bars` maps the BarSpecification to a `BinanceKlineInterval` and then rejects `Second1`. The check runs before the `@kline_` stream name is formed, so no WebSocket subscription is attempted.
Source
Thrown at crates/adapters/binance/src/futures/data.rs:2028
// Binance Futures uses aggTrade for aggregate trades
let stream = format!("{}@aggTrade", format_binance_stream_symbol(&instrument_id));
self.spawn_ws(
async move {
ws.subscribe(vec![stream])
.await
.context("trades subscription")
},
"trade subscription",
);
Ok(())
}
fn subscribe_bars(&mut self, cmd: SubscribeBars) -> anyhow::Result<()> {
let bar_type = cmd.bar_type;
let ws = self.ws_client.clone();
let interval = bar_spec_to_binance_interval(bar_type.spec())?;
anyhow::ensure!(
interval != crate::common::enums::BinanceKlineInterval::Second1,
"Binance Futures does not support second-level kline intervals"
);
let stream = format!(
"{}@kline_{}",
format_binance_stream_symbol(&bar_type.instrument_id()),
interval.as_str()
);
self.spawn_ws(
async move {
ws.subscribe(vec![stream])
.await
.context("bars subscription")
},
"bar subscription",
);View on GitHub (pinned to a4b06ed870)
Solutions
- Use a bar step of 1 minute or larger (1-MINUTE, 5-MINUTE, 1-HOUR, ...) for Binance Futures
- If 1-second bars are required, subscribe to the trade stream and aggregate 1s bars locally (INTERNAL aggregation from trades)
Example fix
# before
bar_type = BarType.from_str('BTCUSDT-PERP.BINANCE-1-SECOND-LAST-EXTERNAL')
actor.subscribe_bars(bar_type)
# after
bar_type = BarType.from_str('BTCUSDT-PERP.BINANCE-1-MINUTE-LAST-EXTERNAL')
actor.subscribe_bars(bar_type) Defensive patterns
Strategy: validation
Validate before calling
from nautilus_trader.model.data import BarSpecification, BarAggregation
def is_second_aggregated(bar_spec) -> bool:
return bar_spec.aggregation == BarAggregation.SECOND and bar_spec.step == 1
if is_second_aggregated(bar_type.spec):
raise ValueError('Binance Futures has no 1-second klines; use >= 1-minute steps or aggregate trades locally')
actor.subscribe_bars(bar_type) Type guard
def is_supported_futures_kline_step(bar_spec) -> bool:
return not (bar_spec.aggregation == BarAggregation.SECOND and bar_spec.step == 1) Try / catch
try:
actor.subscribe_bars(bar_type)
except Exception as e:
if 'second-level kline intervals' in str(e):
raise ValueError('Binance Futures klines start at 1 minute; subscribe trades and aggregate 1s bars client-side') from e
raise Prevention
- Spot's 1s klines do not exist on futures — never copy spot bar configs to futures unreviewed
- For sub-minute bars, subscribe to the trade stream and build INTERNAL bars from fills
When it happens
Trigger: `subscribe_bars` with a bar type whose step is 1 SECOND, e.g. BarType string `BTCUSDT-PERP.BINANCE-1-SECOND-LAST-EXTERNAL` or INTERNAL — the interval mapping yields `BinanceKlineInterval::Second1` and the ensure fails.
Common situations: Porting a spot 1-second kline config to futures; low-latency strategies that used 1s bars on another venue; backfilling 1-second bars assuming the futures kline endpoint supports them.
Related errors
- Futures mark price requires a BINANCE instrument
- Binance liquidation custom data requires BINANCE venue instr
- historical BinanceBar requests require EXTERNAL aggregation
- historical BinanceBar requests require LAST price type
- historical BinanceBar requests require time aggregation
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/4190b194d7d3c3a1.
Report an issue: GitHub.