nautechsystems/nautilus_trader · error
Negative timestamp not allowed
Error message
Negative timestamp not allowed
What it means
subtract_n_months_nanos converts the result back to u64 nanoseconds for UnixNanos; "Negative timestamp not allowed" means the shifted timestamp is before the UNIX epoch (negative i128/i64 nanos), which the unsigned UnixNanos type cannot hold. The library throws it because nautilus timestamps are non-negative by definition.
Source
Thrown at crates/core/src/datetime.rs:582
///
/// Returns an error if the resulting date would be invalid or out of range.
pub fn add_n_months(datetime: Timestamp, n: u32) -> anyhow::Result<Timestamp> {
shift_months(datetime, i64::from(n))
.map_err(|_| anyhow::anyhow!("Failed to add {n} months to {datetime}"))
}
/// Subtract `n` months from a given UNIX nanoseconds timestamp.
///
/// # Errors
///
/// Returns an error if the resulting timestamp is out of range or invalid.
pub fn subtract_n_months_nanos(unix_nanos: UnixNanos, n: u32) -> anyhow::Result<UnixNanos> {
let datetime = unix_nanos.to_datetime_utc();
let result = subtract_n_months(datetime, n)?;
let timestamp = result.as_nanosecond();
let nanos =
u64::try_from(timestamp).map_err(|_| anyhow::anyhow!("Negative timestamp not allowed"))?;
Ok(UnixNanos::from(nanos))
}
/// Add `n` months to a given UNIX nanoseconds timestamp.
///
/// # Errors
///
/// Returns an error if the resulting timestamp is out of range or invalid.
pub fn add_n_months_nanos(unix_nanos: UnixNanos, n: u32) -> anyhow::Result<UnixNanos> {
let datetime = unix_nanos.to_datetime_utc();
let result = add_n_months(datetime, n)?;
let timestamp = result.as_nanosecond();
let nanos =
u64::try_from(timestamp).map_err(|_| anyhow::anyhow!("Negative timestamp not allowed"))?;
Ok(UnixNanos::from(nanos))
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Check before calling that unix_nanos is large enough: elapsed nanos since epoch >= n months of nanoseconds.
- Clamp the result to 0 (epoch) if a pre-epoch floor is acceptable for your logic.
- Reduce n or use a different anchoring timestamp further from the epoch.
- If pre-epoch values are legitimate for your use case, use jiff Timestamp/i64 arithmetic instead of UnixNanos-based APIs.
Example fix
// before
let anchored = subtract_n_months_nanos(unix_nanos, n)?; // may go pre-epoch
// after
let months_ns: u64 = n as u64 * 30 * 24 * 3600 * 1_000_000_000;
let anchored = if unix_nanos.as_u64() > months_ns {
subtract_n_months_nanos(unix_nanos, n)?
} else {
UnixNanos::from(0u64)
}; Defensive patterns
Strategy: validation
Validate before calling
// Rust: ensure the lookback cannot cross the epoch
const NS_PER_MONTH: u64 = 30 * 24 * 3600 * 1_000_000_000;
fn can_subtract(unix_nanos: UnixNanos, n: u32) -> bool {
unix_nanos.as_u64() > n as u64 * NS_PER_MONTH
} Try / catch
match subtract_n_months_nanos(unix_nanos, n) {
Ok(ns) => ns,
Err(_) => UnixNanos::from(0u64), // clamp to epoch as floor
} Prevention
- Compute the elapsed time since epoch and compare with the requested lookback before subtracting.
- Clamp to epoch 0 when a pre-epoch floor is acceptable in backtests.
When it happens
Trigger: Calling subtract_n_months_nanos(ts, n) where ts is within n months after 1970-01-01, e.g. subtract_n_months_nanos(UnixNanos::from(1970-06-15), 12) or any timer start near the epoch with a large lookback; also from start_timer_internal with a too-large n.
Common situations: Historical backtests replaying data very close to the epoch; subtracting a lookback interval larger than the elapsed time since 1970; misconfigured lookback months (n) in timers.
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
- Negative timestamp: {unix_timestamp_ns}
- DateTime timestamp out of range for UnixNanos: {nanos}
- Execution timestamp '{time_str}' was before Unix epoch
- seconds must be finite, was {secs}
- seconds {secs} is out of range for `u64` nanoseconds
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b7117cb7988cd966.
Report an issue: GitHub.