nautechsystems/nautilus_trader · error

`verification.verifiers` must contain exactly two providers

Error message

`verification.verifiers` must contain exactly two providers

What it means

The blockchain verification subsystem requires exactly two independent verification providers (VERIFICATION_PROVIDER_COUNT = 2) in the `verification.verifiers` config list, validated in `validate_config`. This count constraint ensures cross-verification between a fixed pair of independent sources before results are trusted. The error is thrown by `anyhow::ensure!` at startup when the configured provider count differs from two.

Source

Thrown at crates/adapters/blockchain/src/rpc/verification.rs:1162

    }

    fn provider_ids(&self) -> [String; VERIFICATION_SOURCE_COUNT] {
        source_provider_ids(&self.sources)
    }

    fn failure(&self, read: VerificationRead) -> VerificationFailure {
        VerificationFailure {
            read,
            provider_ids: self.provider_ids(),
        }
    }
}

fn validate_config(
    authoritative_url: &str,
    config: &BlockchainVerificationConfig,
) -> anyhow::Result<()> {
    anyhow::ensure!(
        config.verifiers.len() == VERIFICATION_PROVIDER_COUNT,
        "`verification.verifiers` must contain exactly two providers"
    );
    validate_identity(&config.authoritative)?;
    for verifier in &config.verifiers {
        validate_identity(&verifier.identity)?;
    }

    let identities = [
        &config.authoritative,
        &config.verifiers[0].identity,
        &config.verifiers[1].identity,
    ];
    ensure_distinct(
        identities
            .iter()
            .map(|identity| identity.provider_id.as_str()),
        "provider IDs",

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Configure exactly two entries under `verification.verifiers` in the config file.
  2. Remove any extra verifier entries so the list length is exactly two.
  3. Check for YAML/TOML list merge mistakes (an included file duplicating or dropping verifier entries).
  4. Run the config through `validate_config` before deploy to catch the count early.

Example fix

// before
[verification]
verifiers = ["alchemy"]

// after
[verification]
verifiers = ["alchemy", "infura"]
Defensive patterns

Strategy: validation

Validate before calling

const VERIFICATION_PROVIDER_COUNT: usize = 2;
fn check_verifier_count(cfg: &BlockchainVerificationConfig) -> Result<(), String> {
    if cfg.verifiers.len() != VERIFICATION_PROVIDER_COUNT {
        return Err(format!(
            "verification.verifiers must contain exactly {} providers, got {}",
            VERIFICATION_PROVIDER_COUNT,
            cfg.verifiers.len()
        ));
    }
    Ok(())
}

Type guard

fn has_exactly_two_verifiers(cfg: &BlockchainVerificationConfig) -> bool {
    cfg.verifiers.len() == 2
}

Try / catch

match validate_config(&cfg) {
    Ok(()) => start_with_config(cfg),
    Err(e) if e.to_string().contains("exactly two providers") => {
        eprintln!("Config error: {e}; fix verification.verifiers to list exactly 2 providers");
        std::process::exit(1);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `validate_config` (or the config-loading path that invokes it) with a BlockchainVerificationConfig whose `verifiers` vec has length 0, 1, or 3+.

Common situations: Operators leaving `verifiers` empty in the TOML/YAML config; adding a third provider for redundancy without realizing the count is fixed; deleting a provider entry during an outage; a config template with only one provider filled in.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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