nautechsystems/nautilus_trader · error

Unsealed transaction payload is {} bytes, exceeding the {} b

Error message

Unsealed transaction payload is {} bytes, exceeding the {} byte limit

What it means

Post-decryption sanity check in `unseal`: after successful authentication, the recovered plaintext is re-checked against `MAX_SIGNED_TRANSACTION_BYTES`. This catches envelopes that authenticate but claim or contain an implausibly large payload, defending against crafted or oversized plaintext.

Source

Thrown at crates/adapters/blockchain/src/execution/sealing.rs:209

    ) -> anyhow::Result<Vec<u8>> {
        validate_context(context, &self.deployment_id)?;
        let parsed = parse_envelope(envelope)?;
        let key = self.keys.get(&parsed.key_id).ok_or_else(|| {
            anyhow::anyhow!(
                "Payload sealing key {} is not configured",
                hex::encode(parsed.key_id)
            )
        })?;
        let aad = encode_aad(&parsed.key_id, context)?;
        let nonce = Nonce::try_assume_unique_for_key(parsed.nonce)
            .map_err(|_| anyhow::anyhow!("Signed transaction payload nonce is invalid"))?;
        let mut plaintext = parsed.ciphertext_and_tag.to_vec();
        let plaintext_len = key
            .open_in_place(nonce, Aad::from(aad), &mut plaintext)
            .map_err(|_| anyhow::anyhow!("Signed transaction payload authentication failed"))?
            .len();
        plaintext.truncate(plaintext_len);
        anyhow::ensure!(
            plaintext.len() <= MAX_SIGNED_TRANSACTION_BYTES,
            "Unsealed transaction payload is {} bytes, exceeding the {} byte limit",
            plaintext.len(),
            MAX_SIGNED_TRANSACTION_BYTES
        );
        Ok(plaintext)
    }
}

pub(crate) fn authenticate_payload(
    raw_transaction: &[u8],
    intent: &ExecutionIntentRow,
    hash: &ExecutionTransactionHashRow,
    policy: PayloadPolicy,
    deployment_id: &str,
) -> anyhow::Result<PayloadContext> {
    let context = payload_context(intent, hash, deployment_id)?;
    authenticate_payload_identity(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check whether `MAX_SIGNED_TRANSACTION_BYTES` was reduced; if so, migrate or drop legacy oversized payloads
  2. Re-seal the payload in smaller pieces that satisfy the current limit
  3. Audit how the envelope was produced (custom tooling may have skipped the seal-time size check)

Example fix

// before
let pt = sealer.unseal(&legacy_envelope, &ctx)?; // fails: legacy oversized
// after
assert!(legacy_plaintext.len() <= MAX_SIGNED_TRANSACTION_BYTES, "re-seal required");
Defensive patterns

Strategy: try-catch

Validate before calling

// after unseal succeeds this cannot trigger; guard seal-time instead:
assert!(plaintext.len() <= MAX_SIGNED_TRANSACTION_BYTES);

Try / catch

match sealer.unseal(&envelope, &ctx) {
    Err(e) if e.to_string().contains("Unsealed transaction payload") => {
        migrate_legacy_oversized_payload(envelope)?
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling `unseal` on an envelope whose decrypted plaintext exceeds the maximum byte limit — possible only if such an oversized payload was sealed by code that bypassed the seal-time check, or after a limit downgrade.

Common situations: Envelopes written by older/patched versions with a larger limit, a lowered `MAX_SIGNED_TRANSACTION_BYTES` in the current build, or adversarial envelopes from an attacker with key access.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


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