nautechsystems/nautilus_trader · error

Invalid max_requests_per_second: {max_requests_per_second} e

Error message

Invalid max_requests_per_second: {max_requests_per_second} exceeds maximum

What it means

`default_quota` builds a per-second `governor::Quota` from the caller-supplied `max_requests_per_second`. `Quota::per_second` returns `None` when the burst exceeds the representable maximum, so the adapter converts that into this explicit anyhow error. It indicates the configured rate limit value is outside what the rate limiter supports.

Source

Thrown at crates/adapters/kraken/src/http/spot/client.rs:279

    pub fn reset_cancellation_token(&self) {
        *self.cancellation_token.write() = CancellationToken::new();
    }

    /// Returns a clone of the current cancellation token.
    pub fn cancellation_token(&self) -> CancellationToken {
        self.cancellation_token.read().clone()
    }

    fn default_headers() -> HashMap<String, String> {
        HashMap::from([(USER_AGENT.to_string(), NAUTILUS_USER_AGENT.to_string())])
    }

    fn default_quota(max_requests_per_second: u32) -> anyhow::Result<Quota> {
        let burst = NonZeroU32::new(max_requests_per_second).unwrap_or(
            NonZeroU32::new(KRAKEN_SPOT_DEFAULT_RATE_LIMIT_PER_SECOND).expect("non-zero"),
        );
        Quota::per_second(burst).ok_or_else(|| {
            anyhow::anyhow!(
                "Invalid max_requests_per_second: {max_requests_per_second} exceeds maximum"
            )
        })
    }

    fn rate_limiter_quotas(max_requests_per_second: u32) -> anyhow::Result<Vec<(String, Quota)>> {
        Ok(vec![(
            KRAKEN_GLOBAL_RATE_KEY.to_string(),
            Self::default_quota(max_requests_per_second)?,
        )])
    }

    fn rate_limit_keys(endpoint: &str) -> Vec<String> {
        let normalized = endpoint.split('?').next().unwrap_or(endpoint);
        let route = format!("kraken:spot:{normalized}");
        vec![KRAKEN_GLOBAL_RATE_KEY.to_string(), route]
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Lower `max_requests_per_second` to a realistic value (e.g. Kraken Spot public tier values like 1-20).
  2. Use the default by passing 0: the code substitutes `KRAKEN_SPOT_DEFAULT_RATE_LIMIT_PER_SECOND` when the value is 0.
  3. Check adapter config files/CLI overrides for an implausible rate-limit number.

Example fix

// before
max_requests_per_second: u32::MAX,
// after
max_requests_per_second: 10,
Defensive patterns

Strategy: validation

Validate before calling

fn check_rps(max_requests_per_second: u32) -> Result<(), String> {
    match max_requests_per_second {
        0 => Ok(()), // defaults apply
        1..=100 => Ok(()),
        other => Err(format!("rate limit {} likely exceeds Quota::per_second maximum", other)),
    }
}

Try / catch

let quota = Self::default_quota(cfg.max_requests_per_second)
    .map_err(|e| { log::error!("rate limit config invalid: {e}"); e })?;

Prevention

When it happens

Trigger: Calling the Kraken Spot client constructor (or `default_quota` directly) with `max_requests_per_second` so large that `Quota::per_second(NonZeroU32)` rejects it (exceeds governor's maximum burst, i.e. greater than u32::MAX / period constraints).

Common situations: Passing u32::MAX or a sentinel value like 0xFFFFFFFF as 'unlimited'; misconfigured adapter TOML with an absurd rate limit; copy-paste of a placeholder value.

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/a460331abd21a28c. Report an issue: GitHub.