t8y2/dbx · error

Failed to install rustls crypto provider

Error message

Failed to install rustls crypto provider

What it means

At startup dbx-web installs a rustls crypto provider (aws_lc_rs) as the process-wide default before building TLS clients. install_default() returns Err if a default provider is already installed, and the code panics via expect().

Source

Thrown at crates/dbx-web/src/main.rs:293

        .route("/mq/raw", post(routes::mq::raw_request))
        .route("/mq/send-message", post(routes::mq::send_message))
}

#[cfg(not(feature = "mq-admin"))]
fn add_mq_routes(router: Router<Arc<WebState>>) -> Router<Arc<WebState>> {
    router
}

#[tokio::main]
async fn main() {
    tracing_subscriber::fmt()
        .with_env_filter(
            tracing_subscriber::EnvFilter::try_from_default_env()
                .unwrap_or_else(|_| "dbx_web=info,tower_http=info".parse().unwrap()),
        )
        .init();

    rustls::crypto::aws_lc_rs::default_provider().install_default().expect("Failed to install rustls crypto provider");

    // Data directory
    let data_dir = std::env::var("DBX_DATA_DIR").map(std::path::PathBuf::from).unwrap_or_else(|_| {
        let home = std::env::var("HOME").unwrap_or_else(|_| ".".to_string());
        std::path::PathBuf::from(home).join(".dbx-web")
    });
    std::fs::create_dir_all(&data_dir).expect("Failed to create data directory");

    let app_state = {
        let db_path = data_dir.join("dbx.db");
        let storage = Storage::open(&db_path).await.expect("Failed to open storage");
        storage.migrate_from_json(&data_dir).await.expect("Failed to migrate JSON data");

        // Initialize core dialect registry and load external plugin dialects
        register_core_dialects();
        let registry = DialectRegistry::global();
        let plugin_dirs = vec![data_dir.join("plugins").join("dialects")];
        let load_result = DialectPluginLoader::scan_and_load(registry, &plugin_dirs);

View on GitHub (pinned to c0390bff16)

Solutions

  1. Guard the install: only install if rustls::crypto::CryptoProvider::get_default().is_none().
  2. If embedding, install the provider once at process start before calling dbx-web's main/init.
  3. Ensure only one crypto provider feature is enabled (aws_lc_rs vs ring) to avoid conflicting initialization order.

Example fix

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

Strategy: try-catch

Validate before calling

if rustls::crypto::CryptoProvider::get_default().is_some() {
    // provider already installed; skip install_default
}

Type guard

fn crypto_provider_installed() -> bool {
    rustls::crypto::CryptoProvider::get_default().is_some()
}

Try / catch

if crypto_provider_installed() {
    tracing::debug!("rustls default provider already installed; skipping");
} else {
    rustls::crypto::aws_lc_rs::default_provider()
        .install_default()
        .expect("Failed to install rustls crypto provider");
}

Prevention

When it happens

Trigger: main() runs rustls::crypto::aws_lc_rs::default_provider().install_default().expect(...) when another rustls default provider was already installed earlier in the same process — e.g., an embedding host, a test harness, or another library calling install_default first.

Common situations: Running dbx-web embedded in another binary that configures rustls; tests that init TLS twice; a dependency (e.g., reqwest with rustls feature) installing a provider during an init hook; duplicated main paths in the same binary.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/8df6987fa2a4c0d5. Report an issue: GitHub.