nautechsystems/nautilus_trader · error · anyhow::Error
Replacement execution transaction {} retains signed bytes
Error message
Replacement execution transaction {} retains signed bytes What it means
During the execution-payload storage scan, a row marked as a replacement execution transaction (payload_expected == false) still carries either raw (plaintext) signed transaction bytes or a sealed envelope. The database schema expects replacement rows to retain no transaction payload at all, so this invariant-violation ensure! aborts the scan. It indicates corrupted or incorrectly migrated payload storage.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:5213
LIMIT $2
",
)
.bind(cursor)
.bind(batch_size)
.fetch_all(&mut *transaction)
.await
.context("failed to load execution payload check batch")?;
if rows.is_empty() {
break;
}
for hash in &rows {
cursor = hash.id;
plaintext_rows += u64::from(hash.raw_transaction.is_some());
if !hash.payload_expected {
replacement_rows += 1;
anyhow::ensure!(
hash.raw_transaction.is_none() && hash.sealed_transaction.is_none(),
"Replacement execution transaction {} retains signed bytes",
hash.id
);
continue;
}
original_rows += 1;
let intent = load_execution_intent(&mut transaction, hash.intent_id).await?;
let raw_transaction = if let (Some(keys), Some(deployment_id)) =
(keys, deployment_id.as_deref())
{
anyhow::ensure!(
hash.raw_transaction.is_none(),
"Protected execution transaction {} contains plaintext",
hash.id
);
let envelope = hash.sealed_transaction.as_deref().ok_or_else(|| {
anyhow::anyhow!(View on GitHub (pinned to 18893faf8b)
Solutions
- Identify the offending row id from the message and inspect its raw_transaction/sealed_transaction columns in the execution transactions table.
- Clear the retained payload columns for that replacement row (NULL out raw_transaction and sealed_transaction) after confirming the transaction is truly a replacement that needs no payload.
- Restore the database from a backup taken before the corrupting migration or write.
- Re-run rewrap_execution_payload_storage after fixing the row; it will re-validate the invariant.
Example fix
// Row data before (corrupt)
{ id: "0xabc", payload_expected: false, raw_transaction: "0x02f8...", sealed_transaction: null }
// After (replacement rows must hold no payload)
{ id: "0xabc", payload_expected: false, raw_transaction: null, sealed_transaction: null } Defensive patterns
Strategy: validation
Validate before calling
-- Detect replacement rows retaining payload before rewrap SELECT id FROM execution_transactions WHERE payload_expected = false AND (raw_transaction IS NOT NULL OR sealed_transaction IS NOT NULL);
Prevention
- Run the preflight SQL above as a scheduled health check.
- Test migrations that reclassify rows end-to-end before applying to production.
- Restrict direct writes to the execution transactions table to the sealing writer.
When it happens
Trigger: Raised by the payload scan inside rewrap_execution_payload_storage / begin_execution_payload_rewrap processing when iterating rows: a row with payload_expected=false whose raw_transaction or sealed_transaction column is non-NULL.
Common situations: A failed or partial migration left signed bytes in rows that were later reclassified as replacement transactions; a bug in the payload-sealing writer wrote plaintext into replacement rows; manual DB edits or restore from a divergent backup.
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
- Implement FromRow for FuturesSpread
- Implement FromRow for OptionSpread
- Execution schema version {} is newer than supported version
- Verified finalized transaction count advanced without an act
- Execution payload storage is in {operation} maintenance; com
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/16c1bb829c7495de.
Report an issue: GitHub.