{"record":{"id":"6fee03958b2d6909","repo":"t8y2/dbx","slug":"hive-ca-certificate-contains-no-certificates","errorCode":null,"errorMessage":"Hive CA certificate contains no certificates","messagePattern":"Hive CA certificate contains no certificates","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/argo-go/config.go","lineNumber":1059,"sourceCode":"func buildTLSConfig(params connectParams, values map[string]string, serverName string) (*tls.Config, error) {\n\tenabled := params.SSL || parameterBool(values, \"ssl\") || strings.EqualFold(parameter(values, \"ssl\"), \"true\")\n\tif !enabled {\n\t\treturn nil, nil\n\t}\n\tconfig := &tls.Config{MinVersion: tls.VersionTLS12, ServerName: serverName}\n\tif parameterBool(values, \"sslinsecureskipverify\") || parameterBool(values, \"allowselfsigned\") {\n\t\tconfig.InsecureSkipVerify = true\n\t}\n\tvar customRoots *x509.CertPool\n\tcredentialProviderPath := parameter(values, \"storepasswordpath\")\n\tif path := strings.TrimSpace(params.CACertPath); path != \"\" {\n\t\tcontents, err := os.ReadFile(path)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"read Hive CA certificate: %w\", err)\n\t\t}\n\t\tcustomRoots = x509.NewCertPool()\n\t\tif !customRoots.AppendCertsFromPEM(contents) {\n\t\t\treturn nil, errors.New(\"Hive CA certificate contains no certificates\")\n\t\t}\n\t}\n\ttrustStoreLocation := parameter(values, \"ssltruststore\")\n\tif trustStoreLocation != \"\" {\n\t\tif parameter(values, \"truststorepassword\") == \"\" && credentialProviderPath != \"\" {\n\t\t\treturn nil, errors.New(\"Hive storePasswordPath uses the Java Hadoop credential-provider format; configure trustStorePassword explicitly for the native agent\")\n\t\t}\n\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}","sourceCodeStart":1041,"sourceCodeEnd":1077,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/argo-go/config.go#L1041-L1077","documentation":"This error is thrown during Hive connection TLS setup when the CA certificate file read from disk is parsed but contains no valid PEM-encoded certificates. The library uses x509.AppendCertsFromPEM to populate a custom root pool, and that method returns false when nothing usable was found, so it refuses to continue with an empty trust store rather than silently falling back to system roots.","triggerScenarios":"Calling the Hive driver configuration (config.go, TLS setup path) with the sslrootcert / CA-certificate parameter set to a file path whose contents are not a PEM certificate (wrong file, empty file, DER-encoded cert, or a Java .jks truststore passed by mistake).","commonSituations":"Pointing sslrootcert at a key file or CSR instead of the cert; exporting a certificate in DER format from Windows; passing a Java keystore file where a PEM CA bundle is expected after migrating from the JDBC (Java) Hive driver to the native agent; an empty or truncated file produced by a failed secret mount or ConfigMap projection in Kubernetes.","solutions":["Verify the file contains a PEM block starting with '-----BEGIN CERTIFICATE-----' (run: grep -c 'BEGIN CERTIFICATE' <file>; count must be > 0).","If the certificate is DER-encoded, convert it: openssl x509 -inform DER -in ca.der -out ca.pem, then point the config at ca.pem.","If you accidentally passed a Java truststore (.jks), export its CA to PEM: keytool -exportcert -rfc -keystore truststore.jks -alias ca -file ca.pem, or use the ssltruststore parameter with loadTrustStore instead.","If the file is empty (e.g. failed secret mount), fix the source (re-create the Secret/ConfigMap) and remount, then confirm the file size is non-zero.","If no custom CA is actually needed, remove the CA-certificate parameter so the library uses system roots."],"exampleFix":"// before\nvalues[\"sslrootcert\"] = \"/etc/pki/ca-trust/source/java/cacerts\" // JKS file, no PEM certs\n// after\nvalues[\"sslrootcert\"] = \"/etc/ssl/certs/hive-ca.pem\" // PEM-encoded CA bundle","handlingStrategy":"validation","validationCode":"func validatePEMRoots(path string) error {\n\tb, err := os.ReadFile(path)\n\tif err != nil { return err }\n\tpool := x509.NewCertPool()\n\tif !pool.AppendCertsFromPEM(b) {\n\t\treturn fmt.Errorf(\"%s contains no PEM certificates (check format/encoding)\", path)\n\t}\n\treturn nil\n}\n// run validatePEMRoots(caPath) before building the driver config","typeGuard":"func isPEMCertFile(path string) bool {\n\tb, err := os.ReadFile(path)\n\treturn err == nil && bytes.Contains(b, []byte(\"-----BEGIN CERTIFICATE-----\"))\n}","tryCatchPattern":"caPool, err := buildCAPool(path)\nif err != nil {\n\tif strings.Contains(err.Error(), \"contains no certificates\") {\n\t\t// surface file format guidance / fall back to system roots if policy allows\n\t}\n\treturn err\n}","preventionTips":["Always export/convert certs to PEM ('-----BEGIN CERTIFICATE-----') before referencing them in config.","Never point sslrootcert at a JKS/keystore file; use the dedicated ssltruststore parameter for Java stores.","Add a startup smoke check that calls x509.AppendCertsFromPEM on every configured CA path.","In Kubernetes, verify secret mounts are non-empty before launching the agent."],"tags":["tls","hive","certificate","config"],"backgroundTag":"pem-certificate-parse-failed","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}