nautechsystems/nautilus_trader · error · anyhow::Error
Verified nonce assignment requires the configured failure do
Error message
Verified nonce assignment requires the configured failure domains
What it means
The verified nonce-assignment path requires assignments spanning at least three failure domains, enforced by the ensure! at database.rs:5900. This guarantees the nonce decision is not concentrated in a single failure domain, preserving independent-failure assumptions for the quorum verification.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:5900
/// Assigns the canonical nonce and its authorizing verification evidence atomically.
///
/// # Errors
///
/// Returns an error if the durable nonce ledger, intent ownership, manifest identity, or
/// evidence is inconsistent, or if persistence fails.
pub(crate) async fn assign_execution_intent_nonce_verified(
&self,
assignment: &ExecutionNonceAssignment<'_>,
) -> anyhow::Result<()> {
anyhow::ensure!(
!assignment.decisions.is_empty(),
"Verified nonce assignment requires decision evidence"
);
anyhow::ensure!(
assignment.provider_ids.len() == 3 && assignment.operator_ids.len() == 3,
"Verified nonce assignment requires exactly three provider and operator IDs"
);
anyhow::ensure!(
assignment.failure_domain_ids.len() >= 3,
"Verified nonce assignment requires the configured failure domains"
);
let chain_id = i32::try_from(assignment.chain_id)
.context("Verification chain ID exceeds PostgreSQL INTEGER")?;
let nonce =
i64::try_from(assignment.nonce).context("Execution nonce exceeds PostgreSQL BIGINT")?;
let mut transaction = self
.pool
.begin()
.await
.map_err(|e| anyhow::anyhow!("Failed to start verified nonce assignment: {e}"))?;
let (manifest_version, manifest_digest, next_nonce, revision) =
sqlx::query_as::<_, (String, String, i64, i64)>(
"
SELECT manifest_version, manifest_digest, next_canonical_nonce, revision
FROM execution_verification_nonce
WHERE chain_id = $1 AND wallet_address = $2View on GitHub (pinned to 18893faf8b)
Solutions
- Populate failure_domain_ids with at least three distinct failure domains before calling the verified assignment path.
- Fix the failure-domain configuration/registry so at least three domains are registered and healthy.
- Adjust provider/operator selection to spread across distinct failure domains rather than picking collocated nodes.
- Verify topology metadata ingestion is working (no stale/missing failure-domain labels in the registry).
Example fix
// before: assignment built with whatever domains were handy
let assignment = ExecutionNonceAssignment { failure_domain_ids: domains, .. };
// after
anyhow::ensure!(domains.len() >= 3, "need >=3 failure domains, got {}", domains.len());
let assignment = ExecutionNonceAssignment { failure_domain_ids: domains, .. };
database.assign_execution_intent_nonce_verified(&assignment).await?; Defensive patterns
Strategy: validation
Validate before calling
// validate failure-domain spread before the verified call
let distinct: std::collections::HashSet<_> = assignment.failure_domain_ids.iter().collect();
if distinct.len() < 3 {
return Err(anyhow::anyhow!("verified assignment needs >=3 failure domains, got {}", distinct.len()));
} Type guard
fn spans_enough_failure_domains(a: &ExecutionNonceAssignment<'_>) -> bool {
a.failure_domain_ids.iter().collect::<std::collections::HashSet<_>>().len() >= 3
} Try / catch
match database.assign_execution_intent_nonce_verified(&assignment).await {
Err(e) if e.to_string().contains("configured failure domains") => {
tracing::error!(domains = assignment.failure_domain_ids.len(), "insufficient failure-domain spread");
return Err(e);
}
Ok(()) => {},
Err(e) => return Err(e),
} Prevention
- Register and health-check at least three failure domains before running verified assignments.
- Spread provider/operator selection across distinct failure domains.
- Verify topology metadata is fresh — stale labels collapse domains.
- Alert when the failure-domain registry reports fewer than three healthy domains.
When it happens
Trigger: Passing an ExecutionNonceAssignment whose failure_domain_ids has fewer than 3 entries — typically when providers/operators were selected from overlapping failure domains, the failure-domain registry returned too few domains, or topology metadata was missing so IDs defaulted to one or two.
Common situations: Deployments where the failure-domain configuration (e.g. regions/zones) is not fully populated; providers clustered in one region/zone; a topology service outage returning incomplete failure-domain metadata; misclassification of operator topology in the node registry.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- max_fee_per_contract is required
- max_fee_per_contract must be greater than zero
- Failed to create HTTP client: {e}
- Connect verification evidence is incomplete
- Execution payload check batch size must be positive
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/3d80d870f900f077.
Report an issue: GitHub.