nautechsystems/nautilus_trader · error
Canonical signer-nonce transaction
Error message
Canonical signer-nonce transaction {} has no authenticated retained payload What it means
When the replacement scan finds the canonical transaction with the wallet's nonce, that transaction's raw payload must exist in the authenticated payload set retained locally (authenticated_payloads keyed by tx hash). If the hash is missing, the canonical transaction cannot be authenticated against a locally retained signed payload, so the client fails the reconciliation rather than trusting an unverified transaction.
Solutions
- Ensure all broadcasts go through this client so raw signed payloads are retained before send
- Restore the raw transaction payloads (from logs/backup) or re-derive the signed bytes if deterministic signing is available
- If the transaction was sent externally, treat it as canonical state and re-sync local intent state instead of forcing reconciliation
- Check payload retention/persistence settings and retention windows
Example fix
// before let raw = signed_tx.raw_payload(); // dropped, only hash retained client.broadcast(raw.hash_only()); // after client.retain_authenticated_payload(raw.hash(), raw.encoded_bytes()); client.broadcast(raw);
Defensive patterns
Strategy: validation
Validate before calling
if let Some(tx) = found_canonical_tx {
if !authenticated_payloads.contains_key(&tx.hash) {
return Err("canonical tx payload not retained; cannot authenticate");
}
} Try / catch
match result {
Err(e) if e.to_string().contains("no authenticated retained payload") => {
mark_intent_externally_mined_and_resync()
}
other => other,
} Prevention
- Always broadcast through the client that retains raw payloads
- Persist signed payloads durably before send
- Extend retention windows beyond reconciliation horizons
- Treat out-of-band sends as state changes to sync, not bypass
When it happens
Trigger: A transaction from the wallet with the target nonce was found on-chain, but authenticated_payloads contains no entry for its hash — e.g. the signed raw bytes were never retained (broadcast by another process), retention was lost after a restart, or a replacement transaction from a different session was mined.
Common situations: Transaction broadcast outside this client (manual send, second executor); local payload store pruned or wiped; DB migration losing raw-tx rows; resuming reconciliation after a reinstall without the broadcast payloads.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Canonical nonce advanced without an authenticated signer…
- Canonical nonce is outside the owned reconciliation range…
- Execution intent has no persisted signed transaction bytes
- Execution intent signed transaction failed authentication
- Finalized block changed from to before intent validation
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/4a02bd2f591168bb.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/blockchain/src/execution/client.rs:3153
self.chain_id,
&wallet_address,
end,
&self.manifest_digest,
)
.await?;
if let Some(cursor) = finalized_cursor.as_ref() {
anyhow::ensure!(
parse_verified_header(cursor)? == scanned_tip,
"Replacement scan conflicts with the durable finalized header ledger"
);
}
let mut mismatch = None;
let matched = candidate.and_then(|transaction| {
let Some(raw_transaction) = authenticated_payloads.get(&transaction.hash).cloned()
else {
mismatch = Some(anyhow::anyhow!(
"Canonical signer-nonce transaction {} has no authenticated retained payload",
transaction.hash
));
return None;
};
if let Err(e) = validate_rpc_transaction_matches_payload(transaction, &raw_transaction)
{
mismatch = Some(e.context(format!(
"Canonical signer-nonce transaction {} failed authenticated payload validation",
transaction.hash
)));
return None;
}
Some((transaction.hash, raw_transaction))
});
let matched_hash = matched.as_ref().map(|(hash, _)| hash.to_string());
self.databaseView on GitHub (pinned to 18893faf8b)