{"record":{"id":"ad7855ca8480c1ae","repo":"xai-org/x-algorithm","slug":"env-grpc-mtls-server-key-path-must-be-set","errorCode":null,"errorMessage":"{ENV_GRPC_MTLS_SERVER_KEY_PATH} must be set","messagePattern":"(.+?) must be set","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"visibility-filtering/config.rs","lineNumber":101,"sourceCode":"pub struct GrpcMtlsConfig {\n    pub server_key_path: String,\n    pub server_crt_path: String,\n    pub server_chain_path: Option<String>,\n    pub client_ca_path: String,\n}\n\nimpl GrpcMtlsConfig {\n    pub fn from_env() -> anyhow::Result<Option<Self>> {\n        let enabled = parse_env_flag(std::env::var(ENV_GRPC_MTLS_ENABLED).ok().as_deref());\n\n        if !enabled {\n            return Ok(None);\n        }\n\n        let server_key_path = std::env::var(ENV_GRPC_MTLS_SERVER_KEY_PATH)\n            .ok()\n            .filter(|v| !v.is_empty())\n            .ok_or_else(|| anyhow::anyhow!(\"{ENV_GRPC_MTLS_SERVER_KEY_PATH} must be set\"))?;\n\n        let server_crt_path = std::env::var(ENV_GRPC_MTLS_SERVER_CRT_PATH)\n            .ok()\n            .filter(|v| !v.is_empty())\n            .ok_or_else(|| anyhow::anyhow!(\"{ENV_GRPC_MTLS_SERVER_CRT_PATH} must be set\"))?;\n\n        let server_chain_path = std::env::var(ENV_GRPC_MTLS_SERVER_CHAIN_PATH)\n            .ok()\n            .filter(|v| !v.is_empty());\n\n        let client_ca_path = std::env::var(ENV_GRPC_MTLS_CLIENT_CA_PATH)\n            .ok()\n            .filter(|v| !v.is_empty())\n            .ok_or_else(|| anyhow::anyhow!(\"{ENV_GRPC_MTLS_CLIENT_CA_PATH} must be set\"))?;\n\n        Ok(Some(Self {\n            server_key_path,\n            server_crt_path,","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/visibility-filtering/config.rs#L83-L119","documentation":"Raised in from_env when mTLS is enabled (the earlier check returned Ok(None) only when disabled) but the GRPC_MTLS_SERVER_KEY_PATH environment variable is unset or empty. Server mTLS config cannot be constructed without the server private key path.","triggerScenarios":"Enabling gRPC mTLS in the visibility-filtering service while GRPC_MTLS_SERVER_KEY_PATH is missing from the environment or set to an empty string.","commonSituations":"Deploying with mTLS enabled but the secret/env not mounted; helm/k8s env var name typos; local runs copying config without cert envs; CI missing cert envs.","solutions":["Set GRPC_MTLS_SERVER_KEY_PATH to the path of the server TLS key file (non-empty)","Verify the var is actually injected into the container/pod environment (kubectl exec env | grep GRPC_MTLS)","If mTLS is not intended in this environment, disable the mTLS flag so from_env returns None","Use a startup preflight that checks all four mTLS env vars together and reports all missing ones"],"exampleFix":"# before\n# mTLS enabled, key path missing\n\n# after\nexport GRPC_MTLS_SERVER_KEY_PATH=/etc/certs/server.key\nexport GRPC_MTLS_SERVER_CRT_PATH=/etc/certs/server.crt\nexport GRPC_MTLS_CLIENT_CA_PATH=/etc/certs/client_ca.crt\n# optionally: export GRPC_MTLS_SERVER_CHAIN_PATH=/etc/certs/chain.crt","handlingStrategy":"validation","validationCode":"fn require_env(name: &str) -> Result<String> { std::env::var(name).ok().filter(|v| !v.is_empty()).ok_or_else(|| anyhow::anyhow!(\"{name} must be set\")) }","typeGuard":null,"tryCatchPattern":"null","preventionTips":["Declare all mTLS envs in one secret/config block","Startup preflight lists ALL missing mTLS vars at once","Fail fast before binding ports"],"tags":["mtls","env-var","tls","config","rust"],"backgroundTag":"missing-env-var","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}