nautechsystems/nautilus_trader · critical · anyhow::Error

Unprotected execution payload storage contains {sealed_rows}

Error message

Unprotected execution payload storage contains {sealed_rows} sealed row(s)

What it means

During activation of protected execution payload storage, the library checks whether any execution_transaction_hash rows already have sealed_transaction set. Sealed (encrypted) rows existing before protection is activated cannot be authenticated against any deployment key set, so activation aborts to avoid adopting unverifiable ciphertext.

Source

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

        )
        .bind(EXECUTION_PAYLOAD_COMPONENT)
        .fetch_optional(&mut *transaction)
        .await
        .context("failed to recheck execution payload marker")?;
        if marker.is_some() {
            transaction
                .rollback()
                .await
                .context("failed to release concurrent payload activation")?;
            return Ok(());
        }
        let sealed_rows = sqlx::query_scalar::<_, i64>(
            "SELECT COUNT(*) FROM execution_transaction_hash WHERE sealed_transaction IS NOT NULL",
        )
        .fetch_one(&mut *transaction)
        .await
        .context("failed to inspect pre-activation envelopes")?;
        anyhow::ensure!(
            sealed_rows == 0,
            "Unprotected execution payload storage contains {sealed_rows} sealed row(s)"
        );

        for statement in [
            "
            CREATE OR REPLACE FUNCTION execution_transaction_payload_fence()
            RETURNS TRIGGER AS $$
            DECLARE payload_operation TEXT;
            BEGIN
                IF NEW.raw_transaction IS NOT NULL
                   AND (TG_OP = 'INSERT'
                        OR OLD.raw_transaction IS NULL
                        OR NEW.raw_transaction IS DISTINCT FROM OLD.raw_transaction) THEN
                    SELECT operation INTO payload_operation
                    FROM execution_payload_state
                    WHERE component = 'signed_transactions';
                    IF NOT (

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Purge or re-key the sealed rows: either delete the sealed rows (if the plaintext copies are authoritative) or migrate them using the original keys before re-attempting activation
  2. Determine which deployment sealed the rows and restore/rotate keys accordingly
  3. Restore a consistent pre-corruption backup of execution_transaction_hash
  4. Never hand-edit sealed payloads; use the library's migration path with the correct PayloadKeySet

Example fix

-- inspect offending rows
SELECT id FROM execution_transaction_hash WHERE sealed_transaction IS NOT NULL;
-- remove or migrate them before activation, e.g. delete only if plaintext is authoritative
DELETE FROM execution_transaction_hash WHERE sealed_transaction IS NOT NULL AND raw_transaction IS NOT NULL;
Defensive patterns

Strategy: try-catch

Validate before calling

let sealed: i64 = sqlx::query_scalar(
    "SELECT COUNT(*) FROM execution_transaction_hash WHERE sealed_transaction IS NOT NULL",
).fetch_one(&pool).await?;
if sealed > 0 {
    anyhow::bail!("{sealed} pre-activation sealed rows must be purged or re-keyed before activation");
}

Try / catch

if let Err(e) = activate_payload_storage(&db, &keys).await {
    if let Some(n) = extract_sealed_row_count(&e.to_string()) {
        // locate and remediate those rows, then retry activation
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: Calling the activation path when execution_transaction_hash contains rows with sealed_transaction IS NOT NULL but the schema version marker is absent (unprotected storage already received sealed payloads).

Common situations: A database was partially activated previously then rolled back while data persisted; rows were inserted by a deployment with different keys; manual tampering or a broken migration left sealed rows behind.

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