nautechsystems/nautilus_trader · error · anyhow::Error

Execution payload state is missing

Error message

Execution payload state is missing

What it means

The storage verification routine locks the execution_payload_state row (component = 'signed_transactions') with FOR SHARE and errors if no row exists. This means the protection/metadata row that tracks deployment, protocol version, operation, and active key has never been initialized.

Source

Thrown at crates/adapters/blockchain/src/cache/database.rs:5069

        .await
        .context("failed to mark execution payload storage ready")?;
        Ok(())
    }

    async fn validate_execution_payload_ready(&self, keys: &PayloadKeySet) -> anyhow::Result<()> {
        let mut transaction = self
            .pool
            .begin()
            .await
            .context("failed to start execution payload validation")?;
        let state_row = sqlx::query(
            "SELECT deployment_id, protocol_version, operation, active_key_id \
             FROM execution_payload_state WHERE component = 'signed_transactions' FOR SHARE",
        )
        .fetch_optional(&mut *transaction)
        .await
        .context("failed to lock execution payload state")?
        .ok_or_else(|| anyhow::anyhow!("Execution payload state is missing"))?;
        let state = execution_payload_state_from_row(&state_row)?;
        validate_execution_payload_state(&state, keys)?;
        anyhow::ensure!(
            state.operation == "ready",
            "Execution payload storage is not ready"
        );
        let (payload_fence, payload_constraint) =
            sqlx::query_as::<_, (bool, bool)>(EXECUTION_PAYLOAD_INFRASTRUCTURE_QUERY)
                .fetch_one(&mut *transaction)
                .await
                .context("failed to inspect execution payload protection infrastructure")?;
        anyhow::ensure!(
            payload_fence && payload_constraint,
            "Execution payload storage is marked ready without its write fence or constraint"
        );
        validate_execution_payload_key_inventory(&mut transaction, keys).await?;
        transaction
            .commit()

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Run the execution payload storage initialization/migration to create the state row
  2. Verify you are connected to the intended database/schema
  3. Restore the execution_payload_state row from backup
  4. Check deployment tooling actually ran the init step before starting the node
Defensive patterns

Strategy: validation

Validate before calling

let state: Option<(String,)> = sqlx::query_as("SELECT operation FROM execution_payload_state WHERE component = 'signed_transactions'").fetch_optional(&mut conn).await?;
if state.is_none() { initialize_payload_storage(&mut conn).await?; }

Try / catch

match err.downcast_ref::<String>() {
    Some(msg) if msg.contains("Execution payload state is missing") => initialize_storage().await,
    _ => return Err(err),
}

Prevention

When it happens

Trigger: Calling storage inspection/promotion APIs before the execution payload protection scheme was initialized; the state row was deleted; connecting to a fresh or legacy database never migrated.

Common situations: Pointing the node at an empty/new database without running initialization; restoring a partial backup that omitted execution_payload_state; environment misconfiguration pointing at the wrong database.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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