block/buzz · critical

failed to install rustls crypto provider

Error message

failed to install rustls crypto provider

What it means

buzz-admin installs the ring CryptoProvider as the process-wide rustls default at the top of main(); the comment explains why — the workspace redis TLS feature compiles both aws-lc-rs and ring, so rustls cannot auto-select and would panic on the first rediss:// connection. install_default() returns Err if any provider is already installed, and the .expect turns that into an immediate panic at process start.

Source

Thrown at crates/buzz-admin/src/main.rs:128

#[derive(Subcommand)]
enum ProductFeedbackCommand {
    /// List feedback across every community as JSON.
    List {
        /// Maximum records to return.
        #[arg(long, default_value_t = 100, value_parser = clap::value_parser!(u16).range(1..=1000))]
        limit: u16,
    },
}

#[tokio::main]
async fn main() {
    // Install the ring CryptoProvider for rustls. The workspace redis TLS
    // feature compiles both aws-lc-rs and ring in transitively, so rustls can't
    // auto-select a provider and would panic on the first rediss:// (ElastiCache)
    // Redis TLS connection without this. Mirrors buzz-relay's main().
    rustls::crypto::ring::default_provider()
        .install_default()
        .expect("failed to install rustls crypto provider");

    let cli = Cli::parse();

    let code = match run(cli).await {
        Ok(code) => code,
        Err(e) => {
            eprintln!("error: {e}");
            5
        }
    };
    std::process::exit(code);
}

async fn run(cli: Cli) -> Result<i32> {
    match cli.command {
        Command::GenerateKey => {
            let keys = Keys::generate();
            println!("Public key:  {}", keys.public_key().to_hex());

View on GitHub (pinned to dad5a33865)

Solutions

  1. Make the install idempotent: only install when CryptoProvider::get_default() is None.
  2. Otherwise ensure exactly one provider install site exists across the whole binary (grep for install_default in the dependency tree).
  3. Keep ring as the single choice — buzz-relay's main() uses the same pattern (per the comment); align any new binary on it.
  4. If a test harness must pre-install, use the same provider (ring) so behavior matches production.

Example fix

// before
rustls::crypto::ring::default_provider()
    .install_default()
    .expect("failed to install rustls crypto provider");

// after
if rustls::crypto::CryptoProvider::get_default().is_none() {
    rustls::crypto::ring::default_provider()
        .install_default()
        .expect("failed to install rustls crypto provider");
}
Defensive patterns

Strategy: validation

Validate before calling

// idempotent bootstrap: install only if no provider is set yet
if rustls::crypto::CryptoProvider::get_default().is_none() {
    rustls::crypto::ring::default_provider()
        .install_default()
        .expect("failed to install rustls crypto provider");
}

Try / catch

// only if you embed admin code in a foreign host that you cannot change:
let _ = std::panic::catch_unwind(|| {
    rustls::crypto::ring::default_provider().install_default()
}); // ignore double-install; a provider already exists

Prevention

When it happens

Trigger: rustls::crypto::ring::default_provider().install_default().expect(...) at crates/buzz-admin/src/main.rs:131-133 panics when another CryptoProvider was already installed in the same process: embedding buzz-admin's run path in a test binary that earlier installed aws-lc-rs, a plugin/dependency calling rustls::crypto::aws_lc_rs::default_provider().install_default() first, or a future double-install added to main() itself.

Common situations: Integration tests that initialize rustls for an HTTP mock server before invoking admin code; a dependency upgrading to a rustls version that auto-installs a provider; copy-pasting the provider bootstrap into two crates linked into one binary.

Related errors


AI-assisted analysis of block/buzz@dad5a33865 (2026-08-20). Data as JSON: /api/errors/ad9d0ce6005a9e8c. Report an issue: GitHub.