{"record":{"id":"fe44eb4b99b150dd","repo":"t8y2/dbx","slug":"jks-truststore-contains-no-certificates-fe44eb","errorCode":null,"errorMessage":"JKS truststore contains no certificates","messagePattern":"JKS truststore contains no certificates","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/hive-go/zookeeper_tls.go","lineNumber":111,"sourceCode":"\t\t\t\t\treturn nil, parseErr\n\t\t\t\t}\n\t\t\t\tcertificates = append(certificates, certificate)\n\t\t\tcase store.IsPrivateKeyEntry(alias):\n\t\t\t\tchain, getErr := store.GetPrivateKeyEntryCertificateChain(alias)\n\t\t\t\tif getErr != nil {\n\t\t\t\t\treturn nil, getErr\n\t\t\t\t}\n\t\t\t\tfor _, entry := range chain {\n\t\t\t\t\tcertificate, parseErr := x509.ParseCertificate(entry.Content)\n\t\t\t\t\tif parseErr != nil {\n\t\t\t\t\t\treturn nil, parseErr\n\t\t\t\t\t}\n\t\t\t\t\tcertificates = append(certificates, certificate)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif len(certificates) == 0 {\n\t\t\treturn nil, errors.New(\"JKS truststore contains no certificates\")\n\t\t}\n\t\treturn certificates, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported store type %q\", storeType)\n\t}\n}\n\nfunc loadClientKeyStore(path, password, storeType string) (tls.Certificate, error) {\n\tcontents, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn tls.Certificate{}, err\n\t}\n\tswitch normalizedStoreType(storeType, path) {\n\tcase \"PEM\":\n\t\treturn tls.X509KeyPair(contents, contents)\n\tcase \"PKCS12\":\n\t\tprivateKey, certificate, chain, err := pkcs12.DecodeChain(contents, password)\n\t\tif err != nil {","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/hive-go/zookeeper_tls.go#L93-L129","documentation":"loadTrustStore parses a JKS truststore and collects its embedded certificates; if it finds none, it refuses to build a TLS config because a truststore with zero certificates cannot verify any server. This guards against silently creating a TLS connection with an empty trust anchor set.","triggerScenarios":"Calling buildTLSConfig/buildZooKeeperTLSConfig with a JKS file that contains only keys/secret entries, is corrupt, is password-protected with the wrong password (entries silently skipped), or is an empty file.","commonSituations":"Pointing tls.truststore at a keystore instead of a truststore; JKS exported without the CA chain; wrong truststore password so entries fail to decrypt; file truncated during deployment/upload.","solutions":["Rebuild the truststore to contain the CA certificate chain: keytool -importcert -alias ca -file ca.pem -keystore truststore.jks","Verify the truststore password is correct — wrong passwords cause entries to be skipped","Confirm the file is a JKS truststore (not PKCS12) and matches the configured storeType","Check the file's integrity after deployment (size, keytool -list output shows trustedCertEntry entries)"],"exampleFix":"// before\ntruststore.jks created with:\nkeytool -genkeypair -keystore truststore.jks  // contains only a private key\n// after\nkeytool -importcert -alias rootca -file ca-cert.pem -keystore truststore.jks \\\n  -storepass changeit -noprompt\nkeytool -list -keystore truststore.jks  // must show trustedCertEntry","handlingStrategy":"validation","validationCode":"// Go: precheck truststore before building TLS config\nfunc validateTruststore(path, password string) error {\n    f, err := os.Open(path)\n    if err != nil { return err }\n    defer f.Close()\n    ks := jks.New(sha1.New)\n    if err := ks.Parse(f, []byte(password)); err != nil { return err }\n    if len(ks.CertEntries) == 0 { return errors.New(\"truststore has no certs\") }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"certs, err := loadTrustStore(path, password, \"JKS\")\nif err != nil && strings.Contains(err.Error(), \"no certificates\") {\n    return fmt.Errorf(\"truststore %s has no CAs; re-import the CA chain: %w\", path, err)\n}","preventionTips":["Use keytool -importcert (not -genkeypair) when creating truststores","Verify with keytool -list that trustedCertEntry entries exist","Correctly distinguish keystore (private keys) from truststore (CAs) in deployment docs","Checksum/verify truststore files after deployment to catch truncation"],"tags":["tls","jks","truststore","zookeeper"],"backgroundTag":"empty-truststore","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"}