{"record":{"id":"8d3a643d8bb3ef73","repo":"t8y2/dbx","slug":"hive-client-certificate-and-key-must-be-configured","errorCode":null,"errorMessage":"Hive client certificate and key must be configured together","messagePattern":"Hive client certificate and key must be configured together","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/argo-go/config.go","lineNumber":1085,"sourceCode":"\t\tcertificates, err := loadTrustStore(\n\t\t\ttrustStoreLocation,\n\t\t\tparameter(values, \"truststorepassword\"),\n\t\t\tparameter(values, \"truststoretype\"),\n\t\t)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"load Hive truststore: %w\", err)\n\t\t}\n\t\tif customRoots == nil {\n\t\t\tcustomRoots = x509.NewCertPool()\n\t\t}\n\t\tfor _, certificate := range certificates {\n\t\t\tcustomRoots.AddCert(certificate)\n\t\t}\n\t}\n\tconfig.RootCAs = customRoots\n\tif params.ClientCertPath != \"\" || params.ClientKeyPath != \"\" {\n\t\tif params.ClientCertPath == \"\" || params.ClientKeyPath == \"\" {\n\t\t\treturn nil, errors.New(\"Hive client certificate and key must be configured together\")\n\t\t}\n\t\tcertificate, err := tls.LoadX509KeyPair(params.ClientCertPath, params.ClientKeyPath)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"load Hive client certificate: %w\", err)\n\t\t}\n\t\tconfig.Certificates = []tls.Certificate{certificate}\n\t}\n\tkeyStoreLocation := parameter(values, \"sslkeystore\")\n\tif keyStoreLocation != \"\" {\n\t\tif parameter(values, \"keystorepassword\") == \"\" && credentialProviderPath != \"\" {\n\t\t\treturn nil, errors.New(\"Hive storePasswordPath uses the Java Hadoop credential-provider format; configure keyStorePassword explicitly for the native agent\")\n\t\t}\n\t\tcertificate, err := loadClientKeyStore(\n\t\t\tkeyStoreLocation,\n\t\t\tparameter(values, \"keystorepassword\"),\n\t\t\tparameter(values, \"keystoretype\"),\n\t\t)\n\t\tif err != nil {","sourceCodeStart":1067,"sourceCodeEnd":1103,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/argo-go/config.go#L1067-L1103","documentation":"Mutual TLS for the Hive connection requires both the client certificate and its private key. If exactly one of clientCertPath / clientKeyPath is set, the library aborts with this error because tls.LoadX509KeyPair needs both files and a half-configured mTLS setup is always a mistake.","triggerScenarios":"Calling the Hive TLS config path with only one of params.ClientCertPath or params.ClientKeyPath set (the other empty string).","commonSituations":"DSN/config copied from an example where the key was provided separately by the environment; a secret mount failed so only cert.pem was present; the key file path was omitted because the PEM cert file contains both cert and key (combined PEM is not handled here — both parameters must be set).","solutions":["Set both parameters: clientCertPath to the certificate PEM and clientKeyPath to the matching private key PEM.","If your PEM file combines cert and key, either split it into two files (openssl pkey / openssl x509 extraction) and set both paths, or point both parameters at the same combined file if the loader accepts it.","Check the secret/volume mount so that both files actually exist at runtime (kubectl exec ... ls -l) before the agent starts.","If mTLS is not required (server-only TLS), unset both clientCertPath and clientKeyPath entirely instead of leaving one set."],"exampleFix":"// before\nparams.ClientCertPath = \"/etc/hive/tls/client.crt\"\n// ClientKeyPath left empty\n// after\nparams.ClientCertPath = \"/etc/hive/tls/client.crt\"\nparams.ClientKeyPath = \"/etc/hive/tls/client.key\"","handlingStrategy":"validation","validationCode":"func validateClientTLS(p ConfigParams) error {\n\tif (p.ClientCertPath == \"\") != (p.ClientKeyPath == \"\") {\n\t\treturn errors.New(\"client certificate and key must both be set or both unset\")\n\t}\n\tif p.ClientCertPath != \"\" {\n\t\tif _, err := tls.LoadX509KeyPair(p.ClientCertPath, p.ClientKeyPath); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":"func mtlsComplete(p ConfigParams) bool {\n\treturn (p.ClientCertPath == \"\" && p.ClientKeyPath == \"\") ||\n\t\t(p.ClientCertPath != \"\" && p.ClientKeyPath != \"\")\n}","tryCatchPattern":"cfg, err := buildConfig(params)\nif err != nil {\n\tif strings.Contains(err.Error(), \"configured together\") {\n\t\treturn fmt.Errorf(\"mtls config incomplete: set both clientCertPath and clientKeyPath: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Always configure cert+key as a pair, ideally from the same secret/volume.","Prefer splitting combined PEM files into client.crt and client.key at provisioning time.","Health-check file existence for both paths before starting the agent.","If not using mTLS, ensure both fields are explicitly unset, not just one."],"tags":["tls","mtls","hive","config"],"backgroundTag":"mtls-partial-configuration","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}