EpicGames/lore · error · anyhow::Error

TLS is partially configured: cert_file and pkey_file must…

Error message

TLS is partially configured: cert_file and pkey_file must both be set or both be absent

What it means

GrpcServerBuilder's TLS setup for the public gRPC server requires cert_file and pkey_file to be set together or not at all; any other combination (only cert, only key, or a chain without both) returns this error. A half-configured TLS server could not terminate TLS correctly.

Solutions

  1. Set both cert_file and pkey_file, or remove both to run plaintext gRPC.
  2. Verify both files exist and the config keys are spelled correctly.
  3. If TLS is desired but the chain is the only extra item, still ensure cert+key are both present alongside it.

Example fix

// before (config)
[grpc.tls]
cert_file = "/certs/grpc.pem"
// pkey_file missing
// after
[grpc.tls]
cert_file = "/certs/grpc.pem"
pkey_file = "/certs/grpc.key"
Defensive patterns

Strategy: validation

Validate before calling

match (tls.cert_file.as_deref(), tls.pkey_file.as_deref()) {
    (Some(_), Some(_)) | (None, None) => Ok(()),
    _ => Err("grpc TLS needs both cert_file and pkey_file or neither".into()),
}

Try / catch

if let Err(e) = build_grpc_server(...) {
    if e.to_string().contains("TLS is partially configured") {
        eprintln!("set both grpc cert_file and pkey_file, or remove both");
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Configuring grpc.tls with cert_file set but pkey_file absent, or vice versa, when constructing the GrpcServer via its builder.

Common situations: Config templates where the key path was intentionally commented out for plaintext mode but the cert remained; secret injection failing for one of the two files; typo in one key so only the other is read.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13). Data as JSON: /api/errors/664383db714d83c1. Report an issue: GitHub.

Appendix: source

Thrown at lore-server/src/grpc/server.rs:459

    hook_dispatcher: Arc<HookDispatcher>,
}

impl GrpcServerBuilder<WantsTlsConfig> {
    pub fn with_tls_config(
        self,
        cert_path: Option<PathBuf>,
        key_path: Option<PathBuf>,
        cert_chain_path: Option<PathBuf>,
    ) -> Result<GrpcServerBuilder<WantsAdminEndpoints>> {
        let tls_config = match (cert_path, key_path) {
            (Some(cert_path), Some(key_path)) => Some(build_server_tls_config(
                cert_path,
                key_path,
                cert_chain_path,
            )?),
            (None, None) => None,
            _ => {
                return Err(anyhow!(
                    "TLS is partially configured: cert_file and pkey_file must both be set or both be absent"
                ));
            }
        };

        Ok(GrpcServerBuilder(WantsAdminEndpoints {
            environment: self.0.environment,
            feature: self.0.feature,
            immutable_store: self.0.immutable_store,
            local_store: self.0.local_store,
            mutable_store: self.0.mutable_store,
            lock_store: self.0.lock_store,
            hook_dispatcher: self.0.hook_dispatcher,
            notification_sender: self.0.notification_sender,
            notification_service: self.0.notification_service,
            tls_config,
        }))
    }

View on GitHub (pinned to 074eb0b0d1)