{"record":{"id":"218e06c1a505c2e2","repo":"t8y2/dbx","slug":"jks-private-key-entry-has-no-certificate-chain","errorCode":null,"errorMessage":"JKS private key entry has no certificate chain","messagePattern":"JKS private key entry has no certificate chain","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/argo-go/zookeeper_tls.go","lineNumber":165,"sourceCode":"\t\t\t\tcontinue\n\t\t\t}\n\t\t\tentry, getErr := store.GetPrivateKeyEntry(alias, passwordBytes)\n\t\t\tif getErr != nil {\n\t\t\t\treturn tls.Certificate{}, getErr\n\t\t\t}\n\t\t\tprivateKey, parseErr := parsePrivateKey(entry.PrivateKey)\n\t\t\tif parseErr != nil {\n\t\t\t\treturn tls.Certificate{}, parseErr\n\t\t\t}\n\t\t\tresult := tls.Certificate{PrivateKey: privateKey}\n\t\t\tfor index, certificate := range entry.CertificateChain {\n\t\t\t\tresult.Certificate = append(result.Certificate, certificate.Content)\n\t\t\t\tif index == 0 {\n\t\t\t\t\tresult.Leaf, _ = x509.ParseCertificate(certificate.Content)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(result.Certificate) == 0 {\n\t\t\t\treturn tls.Certificate{}, errors.New(\"JKS private key entry has no certificate chain\")\n\t\t\t}\n\t\t\treturn result, nil\n\t\t}\n\t\treturn tls.Certificate{}, errors.New(\"JKS keystore contains no private key entry\")\n\tdefault:\n\t\treturn tls.Certificate{}, fmt.Errorf(\"unsupported store type %q\", storeType)\n\t}\n}\n\nfunc normalizedStoreType(storeType, path string) string {\n\tvalue := strings.ToUpper(strings.TrimSpace(storeType))\n\tswitch value {\n\tcase \"P12\", \"PFX\", \"PKCS#12\":\n\t\treturn \"PKCS12\"\n\tcase \"X509\", \"X.509\":\n\t\treturn \"PEM\"\n\tcase \"\":\n\t\tswitch strings.ToLower(filepath.Ext(path)) {","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/argo-go/zookeeper_tls.go#L147-L183","documentation":"loadClientKeyStore extracts a client certificate chain from a JKS keystore for mutual TLS. After appending each chain certificate, if none were collected, it returns this error: the PrivateKeyEntry exists but carries no certificate chain, so a tls.Certificate cannot be constructed.","triggerScenarios":"Building the ZooKeeper TLS config with a keystore whose private key entry has an empty certificate chain, e.g. keytool entries imported without a -chain or generated keypairs whose certs were deleted.","commonSituations":"Keystore created with 'keytool -genkeypair' in a environment where the self-signed chain was truncated; a JKS holding only trusted (TrustedCertEntry) certificates but no PrivateKeyEntry chain; corrupted keystore after migration between JDK versions.","solutions":["Regenerate/repair the entry so the chain is stored: keytool -genkeypair then -importcert the full chain, or use -importkeystore from a PKCS12 that includes the chain","Verify with keytool -list -v -keystore keystore.jks that the entry is PrivateKeyEntry with a chain length >= 1","If only a key without certs is needed, switch to a PEM keystore with cert+key files","Check the store password so the private key entry is fully decrypted"],"exampleFix":"// before: key without chain\n# keytool -genkeypair -alias client -keystore client.jks -dname cn=client\n// after: include full chain\n# keytool -certreq ... && keytool -importcert -file chain.p7b -keystore client.jks -alias client","handlingStrategy":"validation","validationCode":"out, _ := exec.Command(\"keytool\", \"-list\", \"-v\", \"-keystore\", keystorePath,\n    \"-storepass\", password).Output()\nif !strings.Contains(string(out), \"PrivateKeyEntry\") ||\n    !strings.Contains(string(out), \"Certificate chain length:\") {\n    return fmt.Errorf(\"keystore %s lacks a private key with chain\", keystorePath)\n}","typeGuard":null,"tryCatchPattern":"cert, err := buildTLSConfig(...)\nif errors.Is(err, errNoCertChain) { /* regenerate keystore */ }","preventionTips":["Generate client keystores from PKCS12 bundles that include key + full chain","Run keytool -list -v as a pre-flight check in deployment scripts","Do not reuse truststores as client keystores"],"tags":["tls","jks","keystore","client-cert","mtls"],"backgroundTag":"missing-certificate-chain","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"}