nautechsystems/nautilus_trader · error

Persisted signed transaction is not a complete EIP-2718 enve

Error message

Persisted signed transaction is not a complete EIP-2718 envelope

What it means

decode_signed_transaction calls TxEnvelope::decode_2718_exact, which requires the raw bytes to be exactly one complete EIP-2718 typed-transaction envelope with no trailing bytes. If RLP decoding fails (malformed bytes, truncation, or trailing garbage), the error is replaced with this message. It guards the persisted (sealed/persisted) transaction record's integrity.

Source

Thrown at crates/adapters/blockchain/src/execution/transaction.rs:201

pub(super) struct DecodedSignedTransaction {
    pub hash: B256,
    pub signer: Address,
    pub chain_id: u64,
    pub nonce: u64,
    pub to: Address,
    pub value: U256,
    pub input: Bytes,
    pub gas_limit: u64,
    pub max_fee_per_gas: u128,
    pub max_priority_fee_per_gas: u128,
}

/// Decodes and authenticates one complete signed EIP-1559 transaction.
pub(super) fn decode_signed_transaction(
    raw_transaction: &[u8],
) -> anyhow::Result<DecodedSignedTransaction> {
    let envelope = TxEnvelope::decode_2718_exact(raw_transaction).map_err(|_| {
        anyhow::anyhow!("Persisted signed transaction is not a complete EIP-2718 envelope")
    })?;
    let TxEnvelope::Eip1559(signed) = envelope else {
        anyhow::bail!("Persisted signed transaction is not EIP-1559");
    };
    anyhow::ensure!(
        signed.signature().normalize_s().is_none(),
        "Persisted transaction signature is not EIP-2 normalized"
    );
    let signer = signed
        .signature()
        .recover_address_from_prehash(&signed.signature_hash())
        .context("failed to recover persisted transaction signer")?;
    let hash = *signed.hash();
    let tx = signed.tx();
    let TxKind::Call(to) = tx.to else {
        anyhow::bail!("Signed transaction creates a contract instead of calling a destination");
    };
    anyhow::ensure!(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Hex-dump the raw bytes and confirm the EIP-2718 type byte (0x02 for EIP-1559) is present and the RLP length matches the payload length
  2. Re-fetch or re-persist the transaction; if bytes are corrupt the original signed tx must be regenerated
  3. Ensure the caller passes exactly one envelope with no trailing bytes (decode_2718_exact rejects leftovers)
  4. If legacy transactions must be supported, convert/persist them as EIP-1559 envelopes upstream

Example fix

// before
validate_signed_transaction(&legacy_raw_tx_bytes, &intent)?; // legacy tx, no 0x02 prefix
// after
let envelope_bytes = build_eip1559_envelope(legacy_raw_tx_bytes)?;
validate_signed_transaction(&envelope_bytes, &intent)?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_plausible_eip2718_envelope(raw: &[u8]) -> bool {
    matches!(raw.first(), Some(0x01 | 0x02))
        && raw.len() >= 2
        && raw.len() <= 131_072 // sanity ceiling before RLP decode
}

Type guard

fn looks_like_eip1559(raw: &[u8]) -> bool {
    raw.first() == Some(&0x02)
}

Try / catch

match validate_signed_transaction(&raw, &intent) {
    Ok(()) => (),
    Err(e) if e.to_string().contains("complete EIP-2718 envelope") => {
        // corrupted or wrong-format persisted bytes; re-fetch or re-persist
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling decode_signed_transaction (via validate_signed_transaction, validate_rpc_transaction_matches_payload, or verify_finalized_transaction_identity) with bytes that are not a valid EIP-2718 envelope: truncated RLP, trailing bytes after the envelope, legacy (non-typed) raw tx bytes without an envelope prefix, or corrupt storage.

Common situations: Persisted tx blob corrupted by a DB migration; caller passes a legacy 0x02-less signed transaction; hex-decoding produced extra bytes; concatenated transaction blobs.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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