nautechsystems/nautilus_trader · critical

Canonical nonce advanced without an authenticated signer tra

Error message

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

What it means

The client tracks the signer account's nonce against the chain's canonical head. This error is thrown when the canonical nonce has advanced to a value higher than what this client last authenticated, yet no transaction signed by this signer was found within the canonical block range it inspected. It is a safety check against nonce drift — the account moved without a locally-verifiable cause, so the client refuses to proceed with stale nonce assumptions.

Source

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

                wallet_address: &wallet_address,
                nonce,
                finalized_cursor: finalized_cursor.as_ref(),
                matched_transaction_hash: matched_hash.as_deref(),
                manifest_version: &self.manifest_version,
                manifest_digest: &self.manifest_digest,
                provider_ids: &self.provider_ids,
                operator_ids: &self.operator_ids,
                failure_domain_ids: &self.failure_domain_ids,
                decisions: &decisions,
            })
            .await?;

        if let Some(e) = mismatch {
            return Err(e);
        }

        if matched.is_none() && end == head.number {
            anyhow::bail!(
                "Canonical nonce advanced without an authenticated signer transaction in the canonical range"
            );
        }
        Ok(matched)
    }

    async fn persist_rebroadcast_decisions(
        &self,
        intent_id: i64,
        nonce: u64,
        decisions: &[ExecutionVerificationDecision],
    ) -> anyhow::Result<()> {
        let wallet_address = self.wallet_address.to_string();
        self.database
            .record_execution_verification_batch(&ExecutionVerificationBatch {
                intent_id,
                chain_id: self.chain_id,
                wallet_address: &wallet_address,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pause submissions for this signer and re-sync the nonce from the chain before resuming
  2. Audit for other processes or wallets using the same signer key and stop the contention
  3. Wait for the canonical range to include the missing signer transaction, or wait for chain head to stabilize after a reorg
  4. Restart the client so the nonce cache is rebuilt from the current canonical state

Example fix

// before: resubmitting immediately after nonce error
submit_trade(plan).await?;
// after: resync nonce and confirm no external signer activity
let nonce = client.fetch_account_nonce(signer).await?;
client.reset_cached_nonce(signer, nonce).await?;
submit_trade(plan).await?;
Defensive patterns

Strategy: retry

Validate before calling

let chain_nonce = client.fetch_account_nonce(signer).await?;
assert_eq!(chain_nonce, client.cached_nonce(signer), "nonce drifted; resync before submitting");

Try / catch

match res {
    Err(e) if e.to_string().contains("Canonical nonce advanced") => {
        client.resync_nonce(signer).await?;
        retry_later();
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling transaction submission or nonce-verification paths (the function returning the matched canonical nonce) when: the signer sent transactions from another client/wallet, a transaction was replaced or reorged out of the canonical range, or the local nonce cache is behind the chain head with no authenticated tx found between the tracked range and head.number.

Common situations: Shared signing key used by multiple services or bots; manual transfers from the same hot wallet; a chain reorg removing the tx that justified the nonce bump; running a second instance of the trader against the same key; provider switching between endpoints with divergent views of the head.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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