nautechsystems/nautilus_trader · error · anyhow::Error
Binance {field} timestamp is outside the UnixNanos range: {v
Error message
Binance {field} timestamp is outside the UnixNanos range: {value} What it means
A Binance timestamp parses to a value that, once scaled from milliseconds/microseconds to nanoseconds, falls outside the UnixNanos representable range (i64 nanoseconds since epoch). The value is non-negative but absurdly large, so the checked constructor returns None and this error reports the overflow.
Source
Thrown at crates/adapters/binance/src/common/parse.rs:92
pub(crate) fn parse_millis(value: i64, field: &str) -> anyhow::Result<UnixNanos> {
parse_timestamp(value, UnixNanos::from_millis_checked(value), field)
}
pub(crate) fn parse_micros(value: i64, field: &str) -> anyhow::Result<UnixNanos> {
parse_timestamp(value, UnixNanos::from_micros_checked(value), field)
}
fn parse_timestamp(
value: i64,
timestamp: Option<UnixNanos>,
field: &str,
) -> anyhow::Result<UnixNanos> {
timestamp.ok_or_else(|| {
if value < 0 {
anyhow::anyhow!("invalid negative Binance {field} timestamp: {value}")
} else {
anyhow::anyhow!("Binance {field} timestamp is outside the UnixNanos range: {value}")
}
})
}
pub(crate) fn parse_millis_or_init(value: i64, field: &str, ts_init: UnixNanos) -> UnixNanos {
timestamp_or_init(parse_millis(value, field), ts_init)
}
pub(crate) fn parse_micros_or_init(value: i64, field: &str, ts_init: UnixNanos) -> UnixNanos {
timestamp_or_init(parse_micros(value, field), ts_init)
}
fn timestamp_or_init(timestamp: anyhow::Result<UnixNanos>, ts_init: UnixNanos) -> UnixNanos {
match timestamp {
Ok(timestamp) => timestamp,
Err(e) => {
log::warn!("{e}; using initialization timestamp");
ts_initView on GitHub (pinned to a4b06ed870)
Solutions
- Inspect the raw value printed in the message and compare with the expected unit for that field (Binance uses ms for REST, us for some stream payloads)
- Verify the data path - captures, proxies, or transformations between Binance and the adapter that could alter numbers
- If the field is legitimately huge garbage from upstream, report it; do not clamp silently
Example fix
// before let ts = parse_millis(value, "workingTime")?; // value actually microseconds // after let ts = parse_micros(value, "workingTime")?; // match the field's real unit
Defensive patterns
Strategy: type-guard
Validate before calling
fn is_plausible_millis(value: i64) -> bool {
// reject values that cannot scale into i64 nanoseconds: |value| < i64::MAX / 1_000_000
value >= 0 && value <= i64::MAX / 1_000_000
} Type guard
fn is_plausible_unit_timestamp(value: i64, unit_multiplier: i64) -> bool {
value >= 0 && value.checked_mul(unit_multiplier).is_some()
} Try / catch
let ts = match parse_millis(value, field) {
Ok(ts) => ts,
Err(e) => {
log::error!("implausible {field} value {value}: {e} - probable unit mismatch or corrupt payload");
ts_init // explicit fallback, never a silent clamp
}
}; Prevention
- Confirm each Binance field's unit (ms vs us) before wiring a new endpoint into strict parsers
- Alert on any timestamp that fails a plausibility bound (e.g. year > 3000) rather than letting it flow
- Keep proxies/gateways from rewriting numeric fields in exchange responses
When it happens
Trigger: A millis/micros field containing a garbage-huge number, or a value in the wrong unit (e.g. nanoseconds fed where millis are expected) so the x1e6/x1e3 scaling overflows; corrupted or tampered payloads.
Common situations: Unit confusion when mapping fields from Binance's mixed ms/us APIs; corrupted captures; a proxy/gateway mangling numeric fields; clock-source bugs producing nonsense values.
Related errors
- invalid negative Binance {field} timestamp: {value}
- {standard_key_var} not found in config or environment
- {standard_secret_var} not found in config or environment
- missing broker client order ID signal
- invalid O-format broker client order ID payload length
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/aad26c6591640e49.
Report an issue: GitHub.