nautechsystems/nautilus_trader · error
signature expiry overflows Derive signature_expiry_sec: now
Error message
signature expiry overflows Derive signature_expiry_sec: now {now_secs}s plus TTL {ttl_secs}s What it means
When building Derive authentication signatures, the adapter computes expiry as now + TTL using checked_add on u64 seconds. If the addition overflows (astronomically large TTL or clock value), it refuses and raises this message showing both operands. This guards against silently wrapping the expiry timestamp, which would produce an invalid or already-expired signature.
Source
Thrown at crates/adapters/derive/src/execution.rs:3068
let min_ttl_secs = MIN_SIGNATURE_TTL.as_secs();
if signature_expiry_secs <= min_ttl_secs {
anyhow::bail!(
"signature_expiry_secs {signature_expiry_secs}s must be greater than the Derive minimum {min_ttl_secs}s"
);
}
let now_secs_u64 = clock.get_time_ns().as_u64() / 1_000_000_000;
let now_secs = i64::try_from(now_secs_u64).with_context(|| {
format!("current UNIX time {now_secs_u64}s cannot fit in Derive signature_expiry_sec")
})?;
let ttl_secs = i64::try_from(signature_expiry_secs).with_context(|| {
format!(
"signature_expiry_secs {signature_expiry_secs}s cannot fit in Derive signature_expiry_sec"
)
})?;
now_secs.checked_add(ttl_secs).ok_or_else(|| {
anyhow::anyhow!(
"signature expiry overflows Derive signature_expiry_sec: now {now_secs}s plus TTL {ttl_secs}s"
)
})
}
async fn refresh_market_order_quote(
http_client: &DeriveHttpClient,
venue_symbol: &str,
instrument: &DeriveInstrument,
clock: &'static AtomicTime,
) -> anyhow::Result<QuoteTick> {
let ticker = http_client.get_ticker(venue_symbol).await?;
let price_precision = Price::from_decimal(instrument.tick_size)
.with_context(|| format!("invalid Derive tick_size for {venue_symbol}"))?
.precision;
let size_precision = Quantity::from_decimal(instrument.amount_step)
.with_context(|| format!("invalid Derive amount_step for {venue_symbol}"))?
.precision;View on GitHub (pinned to 18893faf8b)
Solutions
- Set the signature TTL to a sane number of seconds (e.g. tens of seconds to a few minutes).
- Verify the config field is in seconds, not milliseconds or another unit.
- Check system clock sanity (NTP) if now_secs looks wrong in the message.
- Reproduce with the printed now/TTL values to confirm which operand is out of range.
Example fix
// before let ttl_secs = u64::MAX; // intended "never expires" // after let ttl_secs = 30; // 30-second signature window
Defensive patterns
Strategy: validation
Validate before calling
fn validate_signature_ttl(ttl_secs: u64) -> Result<(), String> {
const MAX_SANE_TTL: u64 = 3600;
if ttl_secs > MAX_SANE_TTL {
return Err(format!("signature TTL {ttl_secs}s is unreasonably large"));
}
Ok(())
} Try / catch
match compute_signature_expiry(now_secs, ttl_secs) {
Ok(expiry) => /* sign request */,
Err(e) if e.to_string().contains("overflows") => {
log::error!("bad TTL config: {e}");
// fall back to a default TTL before retrying
}
Err(e) => return Err(e),
} Prevention
- Keep signature TTLs to sane values (seconds to minutes)
- Confirm the TTL config unit is seconds
- Sync the system clock with NTP so now_secs is trustworthy
When it happens
Trigger: Configuring a signature TTL so large that now_secs + ttl_secs exceeds u64::MAX seconds; passing a nonsensical/garbage TTL value (e.g. from a mis-parsed config) into the signing routine.
Common situations: TTL set to u64::MAX or some sentinel 'forever' value in config; unit misconfiguration (e.g. providing milliseconds instead of seconds); clock corruption producing absurd now_secs.
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
- Invalid Betfair credentials: username provided but password
- Invalid Betfair credentials: password or app key provided bu
- signature_expiry_secs {signature_expiry_secs}s must be great
- Polymarket {signature_type:?} signature type requires a fund
- Quote spend limit `max_amount` '{}' exceeds the U256 range
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f561cfad3c4f8819.
Report an issue: GitHub.