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
Thrown inside request_binance_bars when the BarAggregation is Second. Binance's futures kline endpoint has no sub-minute interval (its smallest interval is 1m), so any second-level bar request cannot be mapped to a venue interval string and the match arm bails immediately with this fixed message.
Source
Thrown at crates/adapters/binance/src/futures/http/client.rs:2984
/// Returns an error if the bar type is not supported, instrument is not cached,
/// or the request fails.
pub async fn request_binance_bars(
&self,
bar_type: BarType,
start: Option<Timestamp>,
end: Option<Timestamp>,
limit: Option<u32>,
) -> anyhow::Result<Vec<BinanceBar>> {
anyhow::ensure!(
bar_type.aggregation_source() == AggregationSource::External,
"Only EXTERNAL aggregation is supported"
);
let spec = bar_type.spec();
let step = spec.step.get();
let interval = match spec.aggregation {
BarAggregation::Second => {
anyhow::bail!("Binance Futures does not support second-level kline intervals")
}
BarAggregation::Minute => format!("{step}m"),
BarAggregation::Hour => format!("{step}h"),
BarAggregation::Day => format!("{step}d"),
BarAggregation::Week => format!("{step}w"),
BarAggregation::Month => format!("{step}M"),
a => anyhow::bail!("Binance Futures does not support {a:?} aggregation"),
};
let instrument_id = bar_type.instrument_id();
let (symbol, price_precision, size_precision) =
self.cached_precisions_by_id(instrument_id)?;
let params = BinanceKlinesParams {
symbol,
interval,
start_time: start.map(|dt| dt.as_millisecond()),
end_time: end.map(|dt| dt.as_millisecond()),View on GitHub (pinned to a4b06ed870)
Solutions
- Use Minute (or coarser) aggregation for venue kline requests
- For second bars, fetch 1-minute klines or aggTrades and aggregate down locally
- Filter second-level bar types out of batch historical loaders with a skip-and-log instead of failing the whole run
Example fix
// before let bar_type: BarType = "BTCUSDT.BINANCE_PERP-1-SECOND-LAST-EXTERNAL".parse()?; let bars = client.request_binance_bars(bar_type, start, end, None).await?; // after let bar_type: BarType = "BTCUSDT.BINANCE_PERP-1-MINUTE-LAST-EXTERNAL".parse()?; let bars = client.request_binance_bars(bar_type, start, end, None).await?;
Defensive patterns
Strategy: type-guard
Validate before calling
use nautilus_model::data::bar::BarAggregation;
if bar_type.spec().aggregation == BarAggregation::Second {
log::warn!("second bars unsupported on futures; skipping {bar_type}");
} Type guard
fn is_supported_kline_aggregation(bar_type: &BarType) -> bool {
!matches!(
bar_type.spec().aggregation,
BarAggregation::Second | BarAggregation::Tick | BarAggregation::Volume | BarAggregation::Value
)
} Try / catch
Filter second-level bar types out of batch loaders before calling; on error for a single request, skip and continue the batch.
Prevention
- Restrict venue kline requests to Minute..Month
- Build second bars locally from trades
- Skip-and-log unsupported aggregations in generic loaders
When it happens
Trigger: Passing a BarType like 'BTCUSDT.BINANCE_PERP-1-SECOND-LAST-EXTERNAL' to request_binance_bars; generic multi-timeframe loaders that enumerate 1s/5s/15s bars and forward them all to the venue; porting strategies from venues that do support second klines (e.g. some spot APIs or other exchanges).
Common situations: Sub-minute strategies (market making, latency-sensitive signals) requesting venue history; the aggregation step mapping second bars to the interval formatter; users assuming spot and futures kline granularity are identical.
Related errors
- Only EXTERNAL aggregation is supported
- Binance Futures does not support {a:?} aggregation
- invalid Futures kline {}: {e}
- Unsupported second interval: {step}s
- Unsupported minute interval: {step}m
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/38d81b9ac30465e7.
Report an issue: GitHub.