nautechsystems/nautilus_trader · error · anyhow::Error
Execution timestamp '{time_str}' was before Unix epoch
Error message
Execution timestamp '{time_str}' was before Unix epoch What it means
datetime_to_unix_nanos converts a parsed IB timestamp to UnixNanos, which is a u64 count of nanoseconds since the Unix epoch. If the timestamp's nanosecond value is negative (i.e. the datetime predates 1970-01-01), the try_into::<u64> fails and this error is thrown since UnixNanos cannot represent pre-epoch times.
Source
Thrown at crates/adapters/interactive_brokers/src/execution/parse.rs:460
"Unrecognized execution timezone '{tz_str}' in '{time_str}'. Configure TWS / IB Gateway to emit a standard timezone (e.g. UTC)"
)
})?;
let ambiguous = zone.to_ambiguous_timestamp(dt);
match ambiguous.offset() {
AmbiguousOffset::Unambiguous { .. } => Ok(ambiguous.unambiguous()?),
// Fall-back fold: take the earliest instant (worst case ~1h skew).
AmbiguousOffset::Fold { .. } => Ok(ambiguous.earlier()?),
AmbiguousOffset::Gap { .. } => {
anyhow::bail!("Execution timestamp '{time_str}' is non-existent in timezone '{tz_str}'")
}
}
}
fn datetime_to_unix_nanos(dt: Timestamp, time_str: &str) -> anyhow::Result<UnixNanos> {
let nanos: u64 = dt
.as_nanosecond()
.try_into()
.map_err(|_| anyhow::anyhow!("Execution timestamp '{time_str}' was before Unix epoch"))?;
Ok(UnixNanos::new(nanos))
}
#[cfg(test)]
mod tests {
use ibapi::{
contracts::Contract,
orders::{Action, ExecutionSide, Liquidity, Order, OrderStatusKind},
};
use nautilus_model::{
enums::TrailingOffsetType,
identifiers::{Symbol, Venue},
instruments::{InstrumentAny, stubs::equity_aapl},
};
use rust_decimal::Decimal;
use super::*;
use crate::{View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the offending time_str in the error; a pre-epoch execution timestamp indicates corrupted input data that should be fixed at the source.
- Validate the parsed year is >= 1970 before conversion and reject such execution records early.
- Check machine clock/timezone configuration on the gateway host if timestamps are unexpectedly far in the past.
Example fix
// before
let nanos: u64 = dt
.as_nanosecond()
.try_into()
.map_err(|_| anyhow::anyhow!("Execution timestamp '{time_str}' was before Unix epoch"))?;
// after
if dt.as_nanosecond() < 0 {
anyhow::bail!("Execution timestamp '{time_str}' was before Unix epoch");
}
let nanos: u64 = dt
.as_nanosecond()
.try_into()
.map_err(|_| anyhow::anyhow!("Execution timestamp '{time_str}' was before Unix epoch"))?; Defensive patterns
Strategy: validation
Validate before calling
// Rust: reject pre-epoch timestamps before conversion
fn is_post_epoch(dt: &Timestamp) -> bool {
dt.as_nanosecond() >= 0
} Type guard
fn epoch_safe_nanos(dt: Timestamp) -> Option<u64> {
u64::try_from(dt.as_nanosecond()).ok()
} Try / catch
match u64::try_from(dt.as_nanosecond()) {
Ok(nanos) => Ok(UnixNanos::new(nanos)),
Err(_) => {
tracing::error!("Execution timestamp '{time_str}' predates Unix epoch; skipping record");
return Ok(());
}
} Prevention
- Sanity-check parsed execution years (>= 1970, not far future) before conversion
- Fix corrupted source data rather than widening UnixNanos to signed
- Verify gateway host clock and timezone configuration
When it happens
Trigger: parse_execution_time calls datetime_to_unix_nanos with a Timestamp before 1970-01-01 — e.g. a corrupted or misparsed execution time like "19691231 23:59:59" that still happens to match the naive format.
Common situations: Corrupt test/paper-trading data; year typos in synthetic fills; timezone localization shifting a near-epoch timestamp across the boundary; upstream system clocks badly misconfigured.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- instrument_ratios list needs to have at least 2 legs
- ratio cannot be zero
- Timeout must be greater than 0
- Timeout must be less than 3600 seconds
- VNC port must be between 5900 and 5999
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/78f07ebe9f39e175.
Report an issue: GitHub.