nautechsystems/nautilus_trader · error

default_leverage requires spot_account_type=Margin

Error message

default_leverage requires spot_account_type=Margin

What it means

Kraken Spot client config validation enforces that `default_leverage` is only valid on a Margin (not Cash) Spot account. Leverage on a Cash account is meaningless and would be rejected or ignored downstream, so `validate()` fails early with this error.

Source

Thrown at crates/adapters/kraken/src/config.rs:299

    /// Returns the WebSocket URL for the configured product type and environment.
    pub fn ws_url(&self) -> String {
        self.ws_url.clone().unwrap_or_else(|| {
            get_kraken_ws_private_url(self.product_type, self.environment).to_string()
        })
    }

    /// Validates config invariants.
    ///
    /// # Errors
    ///
    /// Returns an error if `default_leverage` is set on a Cash account or the demo environment is
    /// used for Spot.
    pub fn validate(&self) -> anyhow::Result<()> {
        validate_product_environment(self.product_type, self.environment)?;

        if self.default_leverage.is_some() && self.spot_account_type == AccountType::Cash {
            anyhow::bail!("default_leverage requires spot_account_type=Margin");
        }
        Ok(())
    }
}

fn validate_product_environment(
    product_type: KrakenProductType,
    environment: KrakenEnvironment,
) -> anyhow::Result<()> {
    if product_type == KrakenProductType::Spot && environment == KrakenEnvironment::Demo {
        anyhow::bail!("Kraken Spot does not support the demo environment");
    }
    Ok(())
}

#[cfg(test)]
mod tests {
    use rstest::rstest;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Remove `default_leverage` from the config, or
  2. Set `spot_account_type = AccountType::Margin` if the account really is a margin account
  3. Re-run validate() after the change

Example fix

// before
let config = KrakenDataClientConfig {
    spot_account_type: AccountType::Cash,
    default_leverage: Some(Decimal::from(5)),
    ..Default::default()
};
// after
let config = KrakenDataClientConfig {
    spot_account_type: AccountType::Margin,
    default_leverage: Some(Decimal::from(5)),
    ..Default::default()
};
Defensive patterns

Strategy: validation

Validate before calling

if cfg.default_leverage.is_some() && cfg.spot_account_type == AccountType::Cash {
    panic!("default_leverage cannot be set with a Cash spot account");
}
cfg.validate().expect("invalid Kraken config");

Try / catch

match config.validate() {
    Ok(()) => { /* build client */ }
    Err(e) if e.to_string().contains("default_leverage") => {
        config.default_leverage = None;
        /* retry */
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Building a Kraken adapter config with `default_leverage = Some(x)` while `spot_account_type` is `AccountType::Cash`, then calling `validate()` during client construction/connect.

Common situations: Copy-pasting a config template with leverage set while running a cash Spot account; switching spot_account_type to Cash without removing default_leverage.

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