{"record":{"id":"8db8bfca4d8900c3","repo":"EpicGames/lore","slug":"label-certificate-is-partially-configured-certificate-cert","errorCode":null,"errorMessage":"{label} certificate is partially configured: certificate.cert_file and certificate.pkey_file are set but certificate.cert_chain (the CA used to verify client certs) is missing. The endpoint requires mTLS, not server-only TLS","messagePattern":"(.+?) certificate is partially configured: certificate\\.cert_file and certificate\\.pkey_file are set but certificate\\.cert_chain \\(the CA used to verify client certs\\) is missing\\. The endpoint requires mTLS, not server-only TLS","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"lore-server/src/server.rs","lineNumber":566,"sourceCode":"///\n/// Returns:\n/// - `Ok(Mtls)` when `verify_client_certs = true` and `certificate`\n///   carries a full triple (`cert_file` + `pkey_file` + `cert_chain`).\n/// - `Ok(Untrusted)` when `verify_client_certs = false`. The caller is\n///   responsible for emitting a startup warning.\n/// - `Err` when `verify_client_certs = true` but the certificate is\n///   missing or only partially configured.\nfn validate_endpoint_security(\n    label: &str,\n    certificate: Option<&crate::tls::CertificateSettings>,\n    verify_client_certs: bool,\n) -> Result<EndpointSecurity> {\n    if !verify_client_certs {\n        return Ok(EndpointSecurity::Untrusted);\n    }\n    match certificate {\n        Some(cert) if cert.cert_chain.is_some() => Ok(EndpointSecurity::Mtls),\n        Some(_) => Err(anyhow!(\n            \"{label} certificate is partially configured: \\\n             certificate.cert_file and certificate.pkey_file are set but \\\n             certificate.cert_chain (the CA used to verify client certs) \\\n             is missing. The endpoint requires mTLS, not server-only TLS\"\n        )),\n        None => Err(anyhow!(\n            \"{label} requires mTLS to start (verify_client_certs = true). \\\n             Configure certificate.cert_file, certificate.pkey_file, and \\\n             certificate.cert_chain, or set verify_client_certs = false \\\n             to explicitly accept the security exposure\"\n        )),\n    }\n}\n\n#[allow(clippy::too_many_arguments)]\nasync fn launch_grpc_internal_server(\n    settings: Settings,\n    user_agent_filter: Arc<UserAgentFilter>,","sourceCodeStart":548,"sourceCodeEnd":584,"githubUrl":"https://github.com/EpicGames/lore/blob/074eb0b0d1194c997d7cf28b55519e3e197b3e23/lore-server/src/server.rs#L548-L584","documentation":"Thrown by validate_endpoint_security when verify_client_certs is true and a certificate is supplied with cert_file and pkey_file but no cert_chain. Without the CA chain the endpoint cannot verify client certificates, so it would silently degrade to server-only TLS instead of the required mTLS; the server refuses to start rather than misrepresent security.","triggerScenarios":"validate_endpoint_security called with verify_client_certs=true and Some(certificate) where certificate.cert_chain is None while cert_file/pkey_file are set.","commonSituations":"Operator configures the server cert/key pair but forgets the CA bundle used to verify clients; reusing a plain-TLS cert config for an mTLS endpoint; partial migration from TLS to mTLS.","solutions":["Set certificate.cert_chain to the CA certificate file used to verify client certs.","If mTLS is not intended, set verify_client_certs = false to explicitly choose server-only TLS.","Ensure all three fields (cert_file, pkey_file, cert_chain) are present in the same certificate block."],"exampleFix":"# before\n[server.certificate]\ncert_file = \"server.crt\"\npkey_file = \"server.key\"\n\n# after\n[server.certificate]\ncert_file = \"server.crt\"\npkey_file = \"server.key\"\ncert_chain = \"ca.crt\"","handlingStrategy":"validation","validationCode":"if verify_client_certs {\n    match &certificate {\n        Some(c) if c.cert_chain.is_none() => {\n            return Err(anyhow!(\"mTLS requires cert_file, pkey_file, and cert_chain\"));\n        }\n        None => return Err(anyhow!(\"mTLS requires a certificate block\")),\n        _ => {}\n    }\n}","typeGuard":"fn is_full_mtls_triple(cert: &Option<Certificate>) -> bool {\n    matches!(cert, Some(c) if c.cert_file.is_some() && c.pkey_file.is_some() && c.cert_chain.is_some())\n}","tryCatchPattern":null,"preventionTips":["Always configure cert_file, pkey_file, and cert_chain together as a unit.","Lint config files at CI time for mTLS endpoints requiring the full triple.","Explicitly set verify_client_certs = false when server-only TLS is intended."],"tags":["mtls","tls","configuration","security"],"backgroundTag":"missing-required-config-field","analyzedSha":"074eb0b0d1194c997d7cf28b55519e3e197b3e23","analyzedAt":"2026-09-13T09:00:57.509Z","contentChangedAt":"2026-09-13T09:00:57.509Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}