{"record":{"id":"303c88c58efd1693","repo":"BloopAI/vibe-kanban","slug":"failed-to-install-rustls-crypto-provider","errorCode":null,"errorMessage":"Failed to install rustls crypto provider","messagePattern":"Failed to install rustls crypto provider","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/remote/src/main.rs","lineNumber":11,"sourceCode":"use remote::{\n    BillingService, SentrySource, Server, config::RemoteServerConfig, init_tracing,\n    sentry_init_once,\n};\n\n#[tokio::main]\nasync fn main() -> anyhow::Result<()> {\n    // Install rustls crypto provider before any TLS operations\n    rustls::crypto::aws_lc_rs::default_provider()\n        .install_default()\n        .expect(\"Failed to install rustls crypto provider\");\n\n    sentry_init_once(SentrySource::Remote);\n    init_tracing();\n\n    let config = RemoteServerConfig::from_env()?;\n\n    #[cfg(feature = \"vk-billing\")]\n    let billing = {\n        use std::sync::Arc;\n\n        use billing::{BillingConfig, BillingProvider, StripeBillingProvider};\n        use remote::db;\n\n        match BillingConfig::from_env()? {\n            Some(billing_config) => {\n                let pool = db::create_pool(&config.database_url).await?;\n                let provider: Arc<dyn BillingProvider> = Arc::new(StripeBillingProvider::new(\n                    pool,","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/crates/remote/src/main.rs#L1-L29","documentation":"rustls requires exactly one process-wide crypto provider; install_default() returns Err if another provider (ring, aws-lc-rs, or a custom one) was already installed. The code expects it to succeed, so calling main() when a provider was already installed panics with \"Failed to install rustls crypto provider\".","triggerScenarios":"`main` in crates/remote runs and `install_default()` fails because a different rustls CryptoProvider was already installed earlier in the process (e.g. by a dependency using ring::default_provider or a prior install_default call).","commonSituations":"Mixing dependencies that each install a rustls provider (ring vs aws-lc-rs); calling main's logic twice in tests; a library upgrade that now installs its own default provider at startup.","solutions":["Use try_install_default() and ignore the AlreadyInstalled error instead of expect","Ensure only one TLS stack is enabled across Cargo features (prefer rustls with aws-lc-rs everywhere)","If this runs in tests, install the provider once with std::sync::Once in a shared helper"],"exampleFix":"// before\nrustls::crypto::aws_lc_rs::default_provider().install_default().expect(\"Failed to install rustls crypto provider\");\n// after\nlet _ = rustls::crypto::aws_lc_rs::default_provider().try_install_default();","handlingStrategy":"try-catch","validationCode":"// is a CryptoProvider already installed?\nlet provider_installed = std::env::var(\"RUSTLS_CRYPTO_PROVIDER\").is_ok(); // heuristic; runtime state is private\n// safer: use try_install_default and inspect the Result","typeGuard":null,"tryCatchPattern":"match rustls::crypto::aws_lc_rs::default_provider().install_default() {\n    Ok(()) => {},\n    Err(_) => { /* already installed — continue */ }\n}","preventionTips":["Prefer try_install_default() over install_default()+expect","Enable exactly one rustls crypto backend in Cargo features","Guard provider installation with std::sync::Once in shared startup code"],"tags":["rust","panic","rustls","tls"],"backgroundTag":"rustls-crypto-provider-conflict","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}