nautechsystems/nautilus_trader · error

Canonical nonce advanced without an authenticated signer tra

Error message

Canonical nonce advanced without an authenticated signer transaction in the scanned canonical range

What it means

scan_canonical_replacement() computes a scan start block (from a persisted replacement cursor or the intent's creation block) and requires that start be at or before the current canonical head. If the computed start is past the head, the canonical nonce advanced without any authenticated signer transaction being found in the scanned canonical range — an internal consistency violation meaning the ledger and chain state disagree.

Source

Thrown at crates/adapters/blockchain/src/execution/client.rs:3054

        nonce: u64,
        head: VerifiedBlockHeader,
        authenticated_payloads: &HashMap<B256, Vec<u8>>,
    ) -> anyhow::Result<Option<(B256, Vec<u8>)>> {
        let wallet_address = self.wallet_address.to_string();
        let cursor = self
            .database
            .load_execution_replacement_cursor(
                intent.id,
                self.chain_id,
                &wallet_address,
                nonce,
                &self.manifest_digest,
            )
            .await?;
        let start = cursor.as_ref().map_or(intent.created_block, |header| {
            header.number.saturating_add(1)
        });
        anyhow::ensure!(
            start <= head.number,
            "Canonical nonce advanced without an authenticated signer transaction in the scanned canonical range"
        );
        let scan_range = replacement_scan_range(start, head.number)?;
        let end = *scan_range.end();
        let mut decisions = Vec::new();
        let mut blocks = Vec::new();

        if let Some(cursor) = cursor.as_ref() {
            let parent = parse_verified_header(cursor)?;
            let window = required_verification(
                self.verification
                    .verify_replacement_window(parent, end)
                    .await,
                "canonical replacement window",
            )?;
            decisions.push(verification_decision(&window, Some(start), Some(end)));
            blocks = window.value;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the RPC endpoint is fully synced (head block number matches network consensus)
  2. Check the replacement cursor row in the database for the intent and correct or clear it so the scan restarts from intent.created_block
  3. Confirm chain_id and network settings match the chain the intent was created on
  4. If a reorg occurred, re-run reconciliation after the chain stabilizes

Example fix

// before
let head = provider.get_block_number().await?; // lagging replica
// after
let head = provider.get_block_number().await;
ensure!(head >= cursor_block, "RPC head lagging; retry with a synced node");
Defensive patterns

Strategy: validation

Validate before calling

let head = client.head_block_number().await?;
let start = cursor.map_or(intent.created_block, |h| h.number.saturating_add(1));
if start > head {
    return Err("scan start exceeds head; check RPC sync and cursor");
}

Try / catch

match result {
    Err(e) if e.to_string().contains("authenticated signer transaction") => resync_cursor_and_retry(),
    other => other,
}

Prevention

When it happens

Trigger: The durable replacement cursor (or intent.created_block) points to a block number greater than the current verified head: e.g. querying a lagging/replica RPC node, a reorg rewound the head, or a corrupted cursor row was loaded from the database.

Common situations: RPC provider failover to a lagging node; database cursor persisted against a different chain or manifest; deep chain reorg after the intent was created; clock/seed misconfiguration pointing at a testnet.

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