nautechsystems/nautilus_trader · error · anyhow::Error
AX timestamp must be non-negative, was {seconds}
Error message
AX timestamp must be non-negative, was {seconds} What it means
ax_timestamp_s_to_unix_nanos converts an ArchitectHUB epoch-seconds field to UnixNanos and guards against negative seconds, which would denote a pre-1970 timestamp. Architect timestamps are always post-epoch, so a negative value means malformed or garbage data from the venue/feed, and the adapter refuses to fabricate a time.
Source
Thrown at crates/adapters/architect_ax/src/common/parse.rs:46
};
use nautilus_model::{
data::BarSpecification,
enums::AggressorSide,
identifiers::{ClientOrderId, TradeId},
types::{Price, Quantity, fixed::FIXED_PRECISION, quantity::QuantityRaw},
};
use super::enums::AxCandleWidth;
const NANOSECONDS_IN_SECOND: u64 = 1_000_000_000;
/// Converts an AX epoch-seconds timestamp to [`UnixNanos`].
///
/// # Errors
///
/// Returns an error if `seconds` is negative (malformed data from AX).
pub fn ax_timestamp_s_to_unix_nanos(seconds: i64) -> anyhow::Result<UnixNanos> {
anyhow::ensure!(
seconds >= 0,
"AX timestamp must be non-negative, was {seconds}"
);
Ok(UnixNanos::from(seconds as u64 * NANOSECONDS_IN_SECOND))
}
/// Converts AX `ts` (seconds) + `tn` (nanoseconds) fields to [`UnixNanos`].
///
/// # Errors
///
/// Returns an error if `seconds` is negative (malformed data from AX).
pub fn ax_timestamp_stn_to_unix_nanos(seconds: i64, nanos: i64) -> anyhow::Result<UnixNanos> {
anyhow::ensure!(
seconds >= 0,
"AX timestamp must be non-negative, was {seconds}"
);
let nanos_part = nanos.max(0) as u64;
Ok(UnixNanos::from(View on GitHub (pinned to a4b06ed870)
Solutions
- Capture the offending raw message and report it to the nautilus_trader maintainers with the timestamp
- If it comes from your own test fixtures, set non-negative epoch-seconds values
- Check for an architect_ax adapter version mismatch with the live API and upgrade
- Verify the feed account/environment is healthy (resync/reconnect) before suspecting local code
Example fix
// before (fixture) let ts = ax_timestamp_s_to_unix_nanos(-1)?; // AX timestamp must be non-negative, was -1 // after let ts = ax_timestamp_s_to_unix_nanos(1_700_000_000)?;
Defensive patterns
Strategy: try-catch
Type guard
fn is_valid_ax_seconds(seconds: i64) -> bool {
(0..i64::MAX).contains(&seconds)
} Try / catch
// Rust: adapter-level handling
match ax_timestamp_s_to_unix_nanos(ts) {
Ok(nanos) => nanos,
Err(e) => {
tracing::error!("dropping malformed AX message: {e}");
return Ok(()); // skip the corrupt message, keep the stream alive
}
} Prevention
- Record raw venue frames when integrating so malformed messages can be reproduced
- Keep the architect_ax adapter pinned to a version matching the live API
- Use realistic non-negative epoch values in fixtures
When it happens
Trigger: An inbound AX WebSocket message whose ts/seconds field decodes to a negative i64 (corrupted frame, decoding offset bug, or a test fixture with an uninitialised value) reaching ax_timestamp_s_to_unix_nanos.
Common situations: Almost exclusively an adapter/data-feed defect: protocol changes on Architect's side, a buffer misparse after an API update, or hand-crafted fixture data using -1 as a sentinel. End users cannot trigger it with valid config.
Related errors
- AX timestamp_ns must be non-negative, was {nanos}
- Unsupported bar specification for AX: {step}-{:?}
- AX requires whole contract quantities, was {}
- Order quantity must be at least 1 contract
- pandas is required for report generation; install it with `p
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/6333e93c9c0c3461.
Report an issue: GitHub.