stalwartlabs/stalwart · critical
Failed to build the TLS client configuration
Error message
Failed to build the TLS client configuration
What it means
This .expect() fires when ClientConfig::builder_with_provider(...).with_safe_default_protocol_versions() returns an error while building the STRICT rustls client config in crates/utils/src/http.rs:75-77. With a functional aws_lc_rs provider this step is effectively infallible, so an Err means the crypto provider supports none of the default protocol versions. The panic occurs when the SHARED_TLS_CONFIGS LazyLock is first forced.
Source
Thrown at crates/utils/src/http.rs:77
_dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, TlsError> {
Ok(HandshakeSignatureValid::assertion())
}
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
self.0.signature_verification_algorithms.supported_schemes()
}
}
static SHARED_TLS_CONFIGS: LazyLock<SharedTlsConfigs> = LazyLock::new(|| {
let provider = Arc::new(aws_lc_rs::default_provider());
let verifier = rustls_platform_verifier::Verifier::new(provider.clone())
.expect("Failed to load the platform certificate verifier");
let mut strict = ClientConfig::builder_with_provider(provider.clone())
.with_safe_default_protocol_versions()
.expect("Failed to build the TLS client configuration")
.dangerous()
.with_custom_certificate_verifier(Arc::new(verifier))
.with_no_client_auth();
strict.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
let mut insecure = ClientConfig::builder_with_provider(provider.clone())
.with_safe_default_protocol_versions()
.expect("Failed to build the TLS client configuration")
.dangerous()
.with_custom_certificate_verifier(Arc::new(NoCertificateVerification(provider)))
.with_no_client_auth();
insecure.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
let mut strict_http1 = strict.clone();
strict_http1.alpn_protocols = vec![b"http/1.1".to_vec()];
let mut insecure_http1 = insecure.clone();
insecure_http1.alpn_protocols = vec![b"http/1.1".to_vec()];View on GitHub (pinned to e962003857)
Solutions
- Run cargo update / inspect Cargo.lock so rustls, rustls-pki-types and aws-lc-rs versions are mutually compatible (cargo tree -i rustls)
- Ensure aws-lc-rs builds correctly (working cc, cmake, perl/bindgen/go toolchain as required) and the aws_lc_rs feature of rustls is enabled
- If using a custom provider, make sure it registers TLS 1.2/1.3 support before builder_with_provider
- Call init_shared_tls_configs() early in main so the panic surfaces at startup rather than on first network use
Example fix
// before (mismatched dependency graph)
// rustls 0.23.x mixed with an old aws-lc-rs
// after (Cargo.toml, keep in sync)
// rustls = { version = "0.23", features = ["aws_lc_rs"] }
// aws-lc-rs = "1"
// then: cargo update -p aws-lc-rs && cargo build Defensive patterns
Strategy: try-catch
Validate before calling
fn provider_supports_defaults() -> bool {
!aws_lc_rs::default_provider().cipher_suites.is_empty()
}
// plus keep rustls/aws-lc-rs versions aligned: cargo tree -i rustls Try / catch
// the code uses .expect(), so guard by forcing init early and failing fast:
fn main() {
crate::utils::http::init_shared_tls_configs(); // panics here with clear context if broken
// ... rest of app
} Prevention
- Keep rustls, rustls-pki-types and aws-lc-rs on mutually compatible versions; commit Cargo.lock and audit with cargo tree -i rustls
- Ensure CI build images have the toolchain aws-lc-rs needs (cc, cmake, perl, bindgen/go as applicable)
- Run a startup smoke test that builds a TLS client config in CI for every target platform
- Avoid swapping in custom crypto providers without registering TLS 1.2/1.3 support
When it happens
Trigger: First call to init_shared_tls_configs() or shared_tls_config() when the aws_lc_rs default provider reports no supported protocol versions for with_safe_default_protocol_versions() - typically a broken or version-mismatched aws-lc-rs build, or a substituted provider without TLS 1.2/1.3 support.
Common situations: Mixing incompatible rustls / rustls-pki-types / aws-lc-rs versions after cargo update; aws-lc-rs built without a working C compiler/cmake/bindgen; custom crypto providers registered without TLS 1.2/1.3 suites.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Failed to load the platform certificate verifier
- unwrap_tls called on non-TLS acceptor
- failed to install aws-lc-rs as the default rustls crypto pro
- Failed to read {yaml_path:?}
- Node id {node_id} exceeds {MAX_NODE_ID}, panicking to avoid
AI-assisted analysis of stalwartlabs/stalwart@e962003857 (2026-09-06).
Data as JSON: /api/errors/956a32562cb77567.
Report an issue: GitHub.