nautechsystems/nautilus_trader · error

signature_expiry_secs {signature_expiry_secs}s must be great

Error message

signature_expiry_secs {signature_expiry_secs}s must be greater than the Derive minimum {min_ttl_secs}s

What it means

Derive order signatures have a minimum time-to-live (MIN_SIGNATURE_TTL). normal_order_signature_expiry validates that the configured signature_expiry_secs is strictly greater than that minimum, bailing otherwise, before computing the expiry timestamp.

Source

Thrown at crates/adapters/derive/src/execution.rs:3052

                strategy_id,
                instrument_id,
                client_order_id,
                Some(venue_order_id),
                &reason,
                clock.get_time_ns(),
            );
            None
        }
    }
}

fn normal_order_signature_expiry(
    clock: &'static AtomicTime,
    signature_expiry_secs: u64,
) -> anyhow::Result<i64> {
    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"
        )

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Increase signature_expiry_secs in the Derive client config to a value strictly above MIN_SIGNATURE_TTL
  2. Check the MIN_SIGNATURE_TTL constant in the derive adapter for the current minimum
  3. If expiry must be short for safety, restructure to refresh signatures rather than shortening below the minimum

Example fix

// before
DeriveExecClientConfig { signature_expiry_secs: 60, .. } // <= minimum
// after
DeriveExecClientConfig { signature_expiry_secs: 3600, .. }
Defensive patterns

Strategy: validation

Validate before calling

if cfg.signature_expiry_secs <= DERIVE_MIN_SIGNATURE_TTL_SECS {
    return Err(format!("signature_expiry_secs must be > {}", DERIVE_MIN_SIGNATURE_TTL_SECS));
}

Try / catch

match normal_order_signature_expiry(&clock, expiry_secs) {
    Ok(exp) => submit_with(exp),
    Err(e) => { log::error!("config fix needed: {e}"); return Err(e.into()); }
}

Prevention

When it happens

Trigger: Submitting an order with a Derive exec client configured with signature_expiry_secs <= MIN_SIGNATURE_TTL.as_secs(); constructing signature expiry for a normal (non-batch) order.

Common situations: Config copied from another adapter with shorter expiry; user sets expiry to exactly the minimum (must be strictly greater); typo like 30 instead of 300 seconds.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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