block/buzz · error · anyhow::Error

failed to install rustls crypto provider: another provider i

Error message

failed to install rustls crypto provider: another provider is already installed

What it means

Raised in run_relay_main during the CryptoInit startup phase when rustls::crypto::ring::default_provider().install_default() returns AlreadyInstalled. Both aws-lc-rs and ring are compiled in transitively, so the relay must pin ring explicitly; this error fires only if something else (e.g. another component or a prior init) already installed a rustls CryptoProvider in this process. It is a sentinel guard ensuring exactly one provider is configured before any TLS use.

Source

Thrown at crates/buzz-relay/src/main.rs:134

}

async fn run_relay_main(boot: BootTracker) -> anyhow::Result<()> {
    // Install the ring CryptoProvider for rustls. Required before any rustls
    // TLS connection (rediss:// to ElastiCache, wss://, S3 over TLS): both
    // aws-lc-rs and ring are compiled in transitively, so rustls can't
    // auto-select a provider and would panic at first use without this.
    let (mut boot, ()) = boot
        .run_required(
            StartupPhase::CryptoInit,
            || {
                rustls::crypto::ring::default_provider()
                    .install_default()
                    .map_err(|_provider| ())
            },
            |_error| LifecycleReason::ProviderConflict,
        )
        .map_err(|()| {
            anyhow::anyhow!(
                "failed to install rustls crypto provider: another provider is already installed"
            )
        })?;

    // JSON-only structured logs — simple, machine-parseable, CAKE-compatible.
    // If OTEL_EXPORTER_OTLP_ENDPOINT is set, also attach an OpenTelemetry tracing
    // layer that exports spans via OTLP gRPC alongside the JSON stdout logs.
    //
    // Build a single shared Resource (service.name=buzz-relay by default, overridable
    // via OTEL_SERVICE_NAME) for the trace provider so that Datadog can identify
    // spans under the correct service identity.
    let tracing_init = boot.start(StartupPhase::TracingInit);
    let resource = telemetry::service_resource();
    let tracer_init = telemetry::try_init_tracer(resource.clone());
    let otel_enabled = matches!(&tracer_init, telemetry::TracerInit::Enabled(_));
    let otel_layer = match &tracer_init {
        telemetry::TracerInit::Enabled(p) => {
            use opentelemetry::trace::TracerProvider as _;

View on GitHub (pinned to dad5a33865)

Solutions

  1. Remove the duplicate provider installation (install_default call) in the code path that runs before run_relay_main's CryptoInit phase
  2. If a dependency already installs a provider, guard with rustls::crypto::CryptoProvider::get_default() and skip installation when one is present
  3. Verify only one process-wide provider init exists — the relay's own ring install in run_relay_main is normally the only one
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/buzz-relay/src/main.rs:134 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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