{"record":{"id":"53dd7bfbc17f2fe2","repo":"stalwartlabs/stalwart","slug":"failed-to-load-the-platform-certificate-verifier","errorCode":null,"errorMessage":"Failed to load the platform certificate verifier","messagePattern":"Failed to load the platform certificate verifier","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/utils/src/http.rs","lineNumber":73,"sourceCode":"    fn verify_tls13_signature(\n        &self,\n        _message: &[u8],\n        _cert: &CertificateDer<'_>,\n        _dss: &DigitallySignedStruct,\n    ) -> Result<HandshakeSignatureValid, TlsError> {\n        Ok(HandshakeSignatureValid::assertion())\n    }\n\n    fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {\n        self.0.signature_verification_algorithms.supported_schemes()\n    }\n}\n\nstatic SHARED_TLS_CONFIGS: LazyLock<SharedTlsConfigs> = LazyLock::new(|| {\n    let provider = Arc::new(aws_lc_rs::default_provider());\n\n    let verifier = rustls_platform_verifier::Verifier::new(provider.clone())\n        .expect(\"Failed to load the platform certificate verifier\");\n\n    let mut strict = ClientConfig::builder_with_provider(provider.clone())\n        .with_safe_default_protocol_versions()\n        .expect(\"Failed to build the TLS client configuration\")\n        .dangerous()\n        .with_custom_certificate_verifier(Arc::new(verifier))\n        .with_no_client_auth();\n    strict.alpn_protocols = vec![b\"h2\".to_vec(), b\"http/1.1\".to_vec()];\n\n    let mut insecure = ClientConfig::builder_with_provider(provider.clone())\n        .with_safe_default_protocol_versions()\n        .expect(\"Failed to build the TLS client configuration\")\n        .dangerous()\n        .with_custom_certificate_verifier(Arc::new(NoCertificateVerification(provider)))\n        .with_no_client_auth();\n    insecure.alpn_protocols = vec![b\"h2\".to_vec(), b\"http/1.1\".to_vec()];\n\n    let mut strict_http1 = strict.clone();","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/stalwartlabs/stalwart/blob/e96200385781a6a9995a8b839ac27d6c75a983ee/crates/utils/src/http.rs#L55-L91","documentation":"This panic comes from an .expect() while constructing rustls_platform_verifier::Verifier::new() inside the SHARED_TLS_CONFIGS LazyLock in crates/utils/src/http.rs:72-73. The platform verifier relies on the OS certificate store via rustls-platform-verifier, and fails when that platform verification backend cannot be initialized. Because it runs inside a LazyLock initializer, the panic aborts the process the first time a TLS client config is requested (or at init_shared_tls_configs()).","triggerScenarios":"Calling init_shared_tls_configs() or shared_tls_config() (which forces the LazyLock) on a system where rustls_platform_verifier::Verifier::new() cannot load the OS trust store / verifier backend, e.g. minimal Docker images lacking platform verifier support, unsupported OS targets, or a broken system certificate service.","commonSituations":"Running in scratch/alpine/musl Docker images without ca-certificates or the platform verifier proxy; cross-compiled binaries on an OS the crate does not support; hardened/sandboxed environments (no DBus on Linux, restricted macOS Security.framework); tests in minimal CI containers.","solutions":["Install/repair the OS trust store and platform verifier support in the runtime environment (e.g. apt-get install -y ca-certificates on Debian/Ubuntu, apk add ca-certificates on Alpine)","Initialize the shared TLS config explicitly early in main via init_shared_tls_configs() so the failure surfaces at startup with a clear message rather than lazily mid-request","If the platform is unsupported, fall back to a rustls WebPkiServerVerifier / webpki-roots-based ClientConfig instead of the platform verifier","Check the binary targets a supported OS/arch and that the rustls-platform-verifier crate version supports the target platform"],"exampleFix":"// before\nlet verifier = rustls_platform_verifier::Verifier::new(provider.clone())\n    .expect(\"Failed to load the platform certificate verifier\");\n// after\nlet verifier = match rustls_platform_verifier::Verifier::new(provider.clone()) {\n    Ok(v) => v,\n    Err(e) => {\n        log::warn!(\"platform verifier unavailable ({e}); using webpki roots fallback\");\n        build_webpki_fallback_verifier(provider.clone())\n    }\n};","handlingStrategy":"fallback","validationCode":"// probe once at startup:\nfn platform_verifier_ok() -> bool {\n    rustls_platform_verifier::Verifier::new(Arc::new(aws_lc_rs::default_provider())).is_ok()\n}","typeGuard":null,"tryCatchPattern":"// Rust panics are not try/catch-able normally; force the LazyLock at startup\n// and use catch_unwind plus a webpki-roots fallback config when needed:\nlet ok = std::panic::catch_unwind(init_shared_tls_configs).is_ok();\nlet config = if ok { shared_tls_config(false) } else { fallback_webpki_roots_config() };","preventionTips":["Install ca-certificates / the OS trust store in every container image (apt-get install -y ca-certificates or apk add ca-certificates)","Call init_shared_tls_configs() at process start so failures happen deterministically at boot, not on first request","Test the binary on the exact deployment target OS/arch (base image, musl/glibc) in CI","Provide a webpki-roots fallback path for platforms the platform verifier does not support"],"tags":["rust","tls","rustls","certificates","platform-verifier","panic"],"backgroundTag":"tls-platform-verifier-init-failed","analyzedSha":"e96200385781a6a9995a8b839ac27d6c75a983ee","analyzedAt":"2026-09-06T22:07:17.982Z","contentChangedAt":"2026-09-06T22:07:17.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}