nautechsystems/nautilus_trader · error · anyhow::Error

Timestamp overflow for {}

Error message

Timestamp overflow for {}

What it means

request_funding_rates converts each funding entry's effective_at timestamp to UnixNanos (u64 nanoseconds). The error fires when u64::try_from on the nanosecond count fails — i.e. the timestamp is negative (pre-epoch) or exceeds u64 nanosecond range — so the funding rate update cannot be built.

Source

Thrown at crates/adapters/dydx/src/http/client.rs:1374

        let ticker = extract_raw_symbol(instrument_id.symbol.as_str());
        let ts_init = self.generate_ts_init();

        let response = self
            .inner
            .get_historical_funding(ticker, limit, None, end)
            .await?;

        let mut rates = Vec::with_capacity(response.historical_funding.len());

        for entry in &response.historical_funding {
            // Filter by start time if specified
            if start.is_some_and(|s| entry.effective_at < s) {
                continue;
            }

            let ts_event =
                UnixNanos::from(u64::try_from(entry.effective_at.as_nanosecond()).map_err(
                    |_| anyhow::anyhow!("Timestamp overflow for {}", entry.effective_at),
                )?);

            rates.push(FundingRateUpdate::new(
                instrument_id,
                entry.rate,
                Some(60),
                None,
                ts_event,
                ts_init,
            ));
        }

        // dYdX returns newest first; reverse to chronological order
        rates.reverse();

        log::debug!("Fetched {} funding rates for {instrument_id}", rates.len(),);

        Ok(rates)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the raw funding response to see what effective_at values the API actually returns
  2. Filter out entries with implausible effective_at values before conversion
  3. Pin/upgrade the adapter version matching the current dYdV API datetime format
  4. If it is a systematic format change, fix the deserialization of effective_at rather than the conversion

Example fix

// before
let ts_event = UnixNanos::from(u64::try_from(entry.effective_at.as_nanosecond())
    .map_err(|_| anyhow::anyhow!("Timestamp overflow for {}", entry.effective_at))?);
// after
if entry.effective_at < DateTime::default() { continue; } // skip invalid timestamps
let ts_event = UnixNanos::from(u64::try_from(entry.effective_at.as_nanosecond())
    .map_err(|_| anyhow::anyhow!("Timestamp overflow for {}", entry.effective_at))?);
Defensive patterns

Strategy: try-catch

Validate before calling

if entry.effective_at < DateTime::UNIX_EPOCH {
    log::warn!("skipping funding entry with pre-epoch timestamp");
    continue;
}

Type guard

fn has_valid_timestamp(dt: &DateTime<Utc>) -> bool {
    *dt >= DateTime::UNIX_EPOCH && u64::try_from(dt.as_nanosecond()).is_ok()
}

Try / catch

let rates = match client.request_funding_rates(instrument_id, start, end).await {
    Ok(r) => r,
    Err(e) if e.to_string().contains("Timestamp overflow") => {
        log::warn!("bad funding timestamp from API, skipping batch: {e}");
        Vec::new()
    }
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: A funding entry whose effective_at is before the Unix epoch or absurdly far in the future, returned by the dYdX funding rates endpoint, during request_funding_rates.

Common situations: Upstream API change or malformed field returning zero/negative datetimes; timezone misparse producing pre-1970 timestamps; a bad DateTime parsed from the API with wrong precision assumptions.

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/7d987574194f15d7. Report an issue: GitHub.