block/buzz · critical
failed to install rustls crypto provider
Error message
failed to install rustls crypto provider
What it means
rustls 0.23 requires exactly one process-default CryptoProvider. main() installs ring's provider because both ring and aws-lc-rs are compiled in transitively and rustls cannot auto-select. install_default() returns Err only when a default provider is ALREADY installed — the first successful call wins — so this expect means something else in the process set a provider first, and the relay aborts at startup.
Source
Thrown at crates/buzz-relay/src/main.rs:104
}
}
fn allows(&self, _community_id: &Uuid) -> bool {
matches!(self, Self::All)
}
}
const USAGE_METRICS_LOCK_KEY: i64 = 0x4255_5A5A_4D45_5452;
#[tokio::main]
async fn main() -> 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.
rustls::crypto::ring::default_provider()
.install_default()
.expect("failed to install rustls crypto provider");
// 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 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 _;
Some(tracing_opentelemetry::layer().with_tracer(p.tracer("buzz-relay")))
}
_ => None,
};View on GitHub (pinned to eed74bde2f)
Solutions
- Guard the install: only call install_default() when CryptoProvider::get_default().is_none()
- Locate and remove the competing install_default() call (check test setup helpers and newly added dependencies)
- Pin one provider across the workspace via rustls crate features (default-features = false, features = ["ring"]) so no dependency auto-installs another
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
// before any rustls use in tests or embedders:
if rustls::crypto::CryptoProvider::get_default().is_none() {
rustls::crypto::ring::default_provider()
.install_default()
.expect("failed to install rustls crypto provider");
} Try / catch
match rustls::crypto::ring::default_provider().install_default() {
Ok(()) => {}
Err(already) => tracing::debug!("rustls provider already installed: {already:?}"),
} Prevention
- Have exactly one install site for the process-default CryptoProvider and guard it with get_default()
- Align the whole workspace on one rustls provider via crate features so dependencies cannot auto-install a competing one
- In test binaries that also use rustls clients, run the same guarded install in the test harness setup
When it happens
Trigger: A dependency or test setup already called CryptoProvider::install_default() (commonly aws_lc_rs::default_provider()) before relay main ran; embedding or invoking the relay init path twice in one process (tests, sprig-style harnesses) so the second install fails.
Common situations: Adding a crate that transitively installs a rustls provider; integration tests that build rustls-based clients (redis/tokio-postgres/reqwest helpers) and also run relay startup code; rustls version upgrades flipping default provider features.
Related errors
- failed to install rustls crypto provider
- push HTTP client
- mesh ready-registry publish failed: {e}
- mesh endpoint bind on {} failed: {e}
- git pack cache path must be available
AI-assisted analysis of block/buzz@eed74bde2f (2026-08-20).
Data as JSON: /api/errors/83202d03fa31ba61.
Report an issue: GitHub.