{"id":"88684d446ec1ddf9","repo":"actix/actix-web","slug":"failed-to-find-native-root-certificates","errorCode":null,"errorMessage":"Failed to find native root certificates","messagePattern":"Failed to find native root certificates","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"awc/src/client/connector.rs","lineNumber":122,"sourceCode":"            connector: TcpConnector::new(resolver::resolver()).service(),\n            config: ConnectorConfig::default(),\n            tls: Self::build_tls(vec![b\"h2\".to_vec(), b\"http/1.1\".to_vec()]),\n        }\n    }\n\n    cfg_if::cfg_if! {\n        if #[cfg(any(feature = \"rustls-0_23-webpki-roots\", feature = \"rustls-0_23-native-roots\"))] {\n            /// Build TLS connector with Rustls v0.23, based on supplied ALPN protocols.\n            ///\n            /// Note that if other TLS crate features are enabled, Rustls v0.23 will be used.\n            fn build_tls(protocols: Vec<Vec<u8>>) -> OurTlsConnector {\n                use actix_tls::connect::rustls_0_23::{self, reexports::ClientConfig};\n\n                cfg_if::cfg_if! {\n                    if #[cfg(feature = \"rustls-0_23-webpki-roots\")] {\n                        let certs = rustls_0_23::webpki_roots_cert_store();\n                    } else if #[cfg(feature = \"rustls-0_23-native-roots\")] {\n                        let certs = rustls_0_23::native_roots_cert_store().expect(\"Failed to find native root certificates\");\n                    }\n                }\n\n                let mut config = ClientConfig::builder()\n                    .with_root_certificates(certs)\n                    .with_no_client_auth();\n\n                config.alpn_protocols = protocols;\n\n                OurTlsConnector::Rustls023(std::sync::Arc::new(config))\n            }\n        } else if #[cfg(any(feature = \"rustls-0_22-webpki-roots\", feature = \"rustls-0_22-native-roots\"))] {\n            /// Build TLS connector with Rustls v0.22, based on supplied ALPN protocols.\n            fn build_tls(protocols: Vec<Vec<u8>>) -> OurTlsConnector {\n                use actix_tls::connect::rustls_0_22::{self, reexports::ClientConfig};\n\n                cfg_if::cfg_if! {\n                    if #[cfg(feature = \"rustls-0_22-webpki-roots\")] {","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/actix/actix-web/blob/937960ca67f20e14ffe2a075bf6d4593502be12c/awc/src/client/connector.rs#L104-L140","documentation":"Raised by `.expect(\"Failed to find native root certificates\")` at awc/src/client/connector.rs:122 inside `build_tls`, which only compiles when the `rustls-0_23-native-roots` Cargo feature is on. On `Connector` construction (including via `Client::default()`/`Client::builder().finish()`) the library calls `rustls_0_23::native_roots_cert_store()`, which uses the `rustls-native-certs` crate to read the host OS trust store (macOS Keychain, Windows cert store, or `/etc/ssl/certs` on Linux). If that read returns `Err`, `.expect()` panics, crashing the process at startup with no TLS possible.","triggerScenarios":"Constructing an `awc::Connector` or `awc::Client` while the crate was compiled with the `rustls-0_23-native-roots` feature, on a host whose system certificate store returns an error when `rustls-native-certs` reads it (empty result, unreadable bundle, or unsupported platform). The panic fires synchronously during the `Connector::new()` / `build_tls` call, before any request is sent.","commonSituations":"Minimal Docker images (alpine, distroless, `scratch`) that ship without a CA bundle; CI runners with stripped/missing `/etc/ssl/certs/ca-certificates.crt`; locked-down environments where the cert files exist but are not readable by the process user; cross-compilation targets where native cert loading is unsupported; systems where `ca-certificates` was never installed or was purged.","solutions":["Install the OS CA bundle: Debian/Ubuntu `apt-get update && apt-get install -y ca-certificates`; Alpine `apk add --no-cache ca-certificates`; Fedora/RHEL `dnf install -y ca-certificates`.","Switch Cargo features from `rustls-0_23-native-roots` to `rustls-0_23-webpki-roots`, which embeds the Mozilla root program at compile time and removes any runtime OS dependency (best for containers/cross-compile).","If you must use native roots, point `SSL_CERT_FILE` (e.g. `/etc/ssl/certs/ca-certificates.crt`) or `SSL_CERT_DIR` at a valid PEM bundle the process can read.","Verify the bundle is readable by the runtime user (`ls -l /etc/ssl/certs/ca-certificates.crt`) and run `update-ca-certificates` / `ca-certificates update` to regenerate it."],"exampleFix":"# before (awc/Cargo.toml features)\nawc = { features = [\"rustls-0_23-native-roots\"] }\n\n# after - use bundled Mozilla roots, no OS store dependency\nawc = { features = [\"rustls-0_23-webpki-roots\"] }\n\n# or, in a Dockerfile, ensure the bundle is present\nRUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && rm -rf /var/lib/apt/lists/*","handlingStrategy":"validation","validationCode":"// Run before constructing an awc::Connector with rustls-0_23-native-roots.\nfn native_roots_available() -> bool {\n    #[cfg(target_os = \"linux\")]\n    {\n        let candidates = [\n            std::env::var(\"SSL_CERT_FILE\").unwrap_or_default(),\n            \"/etc/ssl/certs/ca-certificates.crt\".into(),\n            \"/etc/pki/tls/certs/ca-bundle.crt\".into(),\n        ];\n        candidates.iter().any(|p| !p.is_empty() && std::path::Path::new(p).exists())\n    }\n    #[cfg(not(target_os = \"linux\"))]\n    { true } // Keychain / Windows store; assume present\n}\n\nif !native_roots_available() {\n    panic!(\"Refusing to build awc::Connector: no native CA bundle found. Install ca-certificates or enable rustls-0_23-webpki-roots.\");\n}","typeGuard":null,"tryCatchPattern":"// The error is a panic via .expect(), so std::try-catch cannot intercept it.\n// Best defense is validation + feature fallback. As a last-resort guard you can\n// catch_unwind, but prefer fixing the environment:\nuse std::panic;\nlet connector = panic::catch_unwind(|| awc::Connector::new());\nmatch connector {\n    Ok(c) => c,\n    Err(_) => { /* log and exit; fix the CA bundle or switch features */ }\n}","preventionTips":["Prefer the `rustls-0_23-webpki-roots` feature for portable/containerized builds so the root set is compiled in.","Bake `ca-certificates` into base Docker images used by the app.","In CI, assert `test -r /etc/ssl/certs/ca-certificates.crt` (or platform equivalent) before running the suite.","Pin awc features in Cargo.toml and review them in code review so `*-native-roots` is a deliberate choice."],"tags":["tls","rustls","certificates","panic","startup","containers"],"analyzedSha":"937960ca67f20e14ffe2a075bf6d4593502be12c","analyzedAt":"2026-08-06T01:15:46.978Z","schemaVersion":2}