nautechsystems/nautilus_trader · error · anyhow::Error

Payload protection requires an active payload key

Error message

Payload protection requires an active payload key

What it means

protect_payload_storage wraps all stored execution payloads with the configured encryption keys. It requires an active payload key; load_payload_keys returning None means no active key is configured, so payloads cannot be authenticated/encrypted and the method refuses to run.

Source

Thrown at crates/adapters/blockchain/src/execution/client.rs:881

            .await
            .map(Into::into)
    }

    /// Activates or resumes protected signed-transaction storage for this execution database.
    ///
    /// Run this while the execution client is disconnected. A full payload check must succeed
    /// before a later execution connection is permitted.
    ///
    /// # Errors
    ///
    /// Returns an error if the client is connected, an active key or deployment identity is
    /// unavailable, or any stored payload cannot be migrated and authenticated.
    pub async fn protect_payload_storage(&self) -> anyhow::Result<()> {
        let database = self.payload_operation_database().await?;
        database.ensure_execution_transaction_schema().await?;
        let keys = self
            .load_payload_keys()?
            .ok_or_else(|| anyhow::anyhow!("Payload protection requires an active payload key"))?;
        database.ensure_execution_payload_storage(&keys).await
    }

    /// Rewraps all protected payloads in this execution database with the configured active key.
    ///
    /// The prior active key must remain configured as a retired key until this method and a
    /// subsequent full check both succeed.
    ///
    /// # Errors
    ///
    /// Returns an error if the client is connected, storage is not protected, required keys are
    /// unavailable, or any bounded rewrap batch fails authentication.
    pub async fn rewrap_payload_storage(&self, batch_size: usize) -> anyhow::Result<()> {
        let batch_size = validate_payload_operation_batch_size(batch_size)?;
        let database = self.payload_operation_database().await?;
        let keys = self
            .load_payload_keys()?
            .ok_or_else(|| anyhow::anyhow!("Payload rewrap requires an active payload key"))?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Configure an active payload key (set up key material so load_payload_keys returns Some)
  2. Provision keys via the documented key setup/rotation procedure before enabling payload protection
  3. Check that the keystore path/env configuration points at valid key files

Example fix

// before
// no payload keys configured
client.protect_payload_storage().await?;
// after
client.configure_payload_keys(active_key, vec![retired_keys]).await?; // ensure an active key exists
client.protect_payload_storage().await?;
Defensive patterns

Strategy: validation

Validate before calling

if client.load_payload_keys()?.is_none() {
    return Err("configure an active payload key before enabling payload protection".into());
}

Try / catch

if let Err(e) = client.protect_payload_storage().await {
    if e.to_string().contains("requires an active payload key") {
        // provision/configure the active key, then retry
    }
    return Err(e.into());
}

Prevention

When it happens

Trigger: Calling protect_payload_storage when no active payload key is configured (load_payload_keys -> None), e.g., key material missing from configuration or keystore.

Common situations: Fresh deployment where payload encryption keys were never provisioned; key file/env var removed or rotated incorrectly leaving no active key; misconfigured keystore path.

Related errors


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