nautechsystems/nautilus_trader · error
valid UTC day start
Error message
valid UTC day start
What it means
`find_closest_smaller_time` floors the current time `now` to the start of its UTC calendar day, then offsets by `daily_time_origin` to find the closest time-bar origin. The `.expect("valid UTC day start")` panics if the timezone library cannot convert a midnight datetime to a `Timestamp`. This is an internal invariant: a UTC midnight date should always convert, so a panic here means a corrupt `now` timestamp or a library bug.
Source
Thrown at crates/model/src/data/bar.rs:341
"Aggregation type {} not supported for time bars",
spec.aggregation
),
}
}
/// Finds the closest smaller time based on a daily time origin and period.
///
/// This function calculates the most recent time that is aligned with the given period
/// and is less than or equal to the current time.
fn find_closest_smaller_time(
now: Timestamp,
daily_time_origin: SignedDuration,
period: SignedDuration,
) -> Timestamp {
// Floor to start of day
let day_start = Offset::UTC
.to_timestamp(Offset::UTC.to_datetime(now).date().at(0, 0, 0, 0))
.expect("valid UTC day start");
let base_time = day_start + daily_time_origin;
let time_difference = base_time.duration_until(now);
let period_ns = period.as_nanos();
debug_assert_ne!(period_ns, 0, "bar period must be non-zero");
// Use div_euclid for floor division (rounds toward -inf, not zero)
// so negative deltas (now before origin) yield the previous period boundary
let num_periods = time_difference.as_nanos().div_euclid(period_ns);
base_time + SignedDuration::from_nanos_i128(num_periods * period_ns)
}
fn duration_days(days: i64) -> SignedDuration {
try_duration_days(days).unwrap_or_else(|e| panic!("{e}"))
}
fn try_duration_days(days: i64) -> anyhow::Result<SignedDuration> {View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the `now` Timestamp passed to get_time_bar_start is a real timestamp within a sane range (e.g. 1970-2100) before aggregation
- Check the source of the timestamp for corruption (data files, fixtures, deserialization)
- Clamp or sanitize out-of-range timestamps upstream of time-bar aggregation
- If it reproduces with a valid timestamp, report as a bug to the nautilus_trader maintainers
Example fix
// before let start = get_time_bar_start(ts_event, daily_time_origin, period); // after const MIN_TS: u64 = 0; const MAX_TS: u64 = 4_102_444_800_000_000_000; // ~2100-01-01 in ns assert!(ts_event.as_u64() > MIN_TS && ts_event.as_u64() < MAX_TS, "timestamp out of range"); let start = get_time_bar_start(ts_event, daily_time_origin, period);
Defensive patterns
Strategy: validation
Validate before calling
def assert_valid_timestamp(ts_ns: int) -> int:
if not (0 < ts_ns < 4_102_444_800_000_000_000): # ~2100-01-01 ns
raise ValueError(f"timestamp {ts_ns} outside sane range")
return ts_ns Type guard
def is_valid_unix_nanos(ts_ns: int) -> bool:
return isinstance(ts_ns, int) and 0 < ts_ns < 4_102_444_800_000_000_000 Prevention
- Sanitize timestamps loaded from external data before aggregation
- Never feed sentinel/placeholder timestamps into time-bar logic
- Range-check timestamps at ingestion boundaries
When it happens
Trigger: Calling `get_time_bar_start` (directly or via time-bar aggregation) with a `now` timestamp outside the representable date range of the chrono/Offset conversion, or with a `Timestamp` value that produces an out-of-range date when floored to midnight.
Common situations: Loading or synthesizing bars with corrupt extreme nanosecond timestamps (e.g. 0 or u64::MAX) from a bad data file; feeding sentinel timestamps into time-based aggregation; upgrading nautilus versions where timestamp range checks changed.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- UnixNanos overflow in from_seconds
- UnixNanos overflow in from_millis
- UnixNanos overflow in from_micros
- seconds timestamp should fit i64
- seconds timestamp should be within valid range
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/7047ea831e01f71c.
Report an issue: GitHub.