nautechsystems/nautilus_trader · error · anyhow::Error

Execution payload marker exists without state

Error message

Execution payload marker exists without state

What it means

acquire_execution_payload_lease reads the execution_payload_state row after confirming the execution_schema_version marker exists. The marker indicates protected payload storage is provisioned, so a missing state row means the two tables are inconsistent (the state row was deleted or never seeded). The library refuses to hand out a lease against half-provisioned protection.

Source

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

        .await
        .context("failed to read execution payload marker")?;

        let version = marker.ok_or_else(|| {
            anyhow::anyhow!("Postgres execution requires protected payload storage")
        })?;
        anyhow::ensure!(
            version == EXECUTION_PAYLOAD_PROTOCOL_VERSION,
            "Unsupported execution payload protection version {version}"
        );
        let 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 marker exists without state"))?;
        let state = execution_payload_state_from_row(&row)?;
        validate_execution_payload_state(&state, keys)?;
        anyhow::ensure!(
            state.operation == "ready",
            "Execution payload storage is in {} maintenance",
            state.operation
        );

        Ok(ExecutionPayloadLease {
            _transaction: transaction,
        })
    }

    /// Reserves one nonce use under the active payload key.
    pub(crate) async fn reserve_execution_payload_seal(
        &self,
        keys: &PayloadKeySet,
    ) -> anyhow::Result<()> {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Re-run the library's execution payload activation/initialization path (activate_execution_payload_storage) to (re)seed the state row
  2. Check execution_payload_state for component='signed_transactions' and restore the missing row from a backup if activation will not recreate it
  3. Never delete rows from execution_payload_state manually; if decommissioning protection, use the library's deactivate/maintenance operations
  4. Restore the database from a consistent backup rather than a partial one

Example fix

-- before (inconsistent db)
SELECT * FROM execution_payload_state; -- empty
-- after: re-run activation via the library API so the state row is seeded
// db.require_execution_payload_storage_ready(&keys).await?;
Defensive patterns

Strategy: try-catch

Validate before calling

let state: Option<_> = sqlx::query(
    "SELECT deployment_id FROM execution_payload_state WHERE component = 'signed_transactions'",
).fetch_optional(&pool).await?;
if state.is_none() {
    return Err(anyhow!("payload state missing; run activation first"));
}

Try / catch

match db.acquire_execution_payload_lease(&keys).await {
    Ok(lease) => { /* sign/broadcast */ }
    Err(e) if e.to_string().contains("marker exists without state") => {
        // re-run activation/initialization, then retry once
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling acquire_execution_payload_lease (used before signing, payload access, acknowledgment, or broadcast) when execution_payload_state has no row for component 'signed_transactions' while the execution_schema_version marker for EXECUTION_PAYLOAD_COMPONENT exists.

Common situations: Partial or interrupted activation of protected storage; someone manually deleted the execution_payload_state row; restoring a database from a partial backup; running against a schema mutated outside the library's activation path.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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