t8y2/dbx · error

JKS keystore contains no private key entry

Error message

JKS keystore contains no private key entry

What it means

loadClientKeyStore looks for a PrivateKeyEntry in a JKS keystore to build the client tls.Certificate. If no private key entry is found at all, it returns this error. The keystore may contain certificates but nothing usable as a client identity for mTLS.

Source

Thrown at agents/drivers/argo-go/zookeeper_tls.go:169

				return tls.Certificate{}, getErr
			}
			privateKey, parseErr := parsePrivateKey(entry.PrivateKey)
			if parseErr != nil {
				return tls.Certificate{}, parseErr
			}
			result := tls.Certificate{PrivateKey: privateKey}
			for index, certificate := range entry.CertificateChain {
				result.Certificate = append(result.Certificate, certificate.Content)
				if index == 0 {
					result.Leaf, _ = x509.ParseCertificate(certificate.Content)
				}
			}
			if len(result.Certificate) == 0 {
				return tls.Certificate{}, errors.New("JKS private key entry has no certificate chain")
			}
			return result, nil
		}
		return tls.Certificate{}, errors.New("JKS keystore contains no private key entry")
	default:
		return tls.Certificate{}, fmt.Errorf("unsupported store type %q", storeType)
	}
}

func normalizedStoreType(storeType, path string) string {
	value := strings.ToUpper(strings.TrimSpace(storeType))
	switch value {
	case "P12", "PFX", "PKCS#12":
		return "PKCS12"
	case "X509", "X.509":
		return "PEM"
	case "":
		switch strings.ToLower(filepath.Ext(path)) {
		case ".jks":
			return "JKS"
		case ".p12", ".pfx", ".pkcs12":
			return "PKCS12"

View on GitHub (pinned to c0390bff16)

Solutions

  1. Swap the config: ensure keystorePath points to the client keystore containing the private key, and truststorePath to the CA store
  2. Recreate the client keystore including the private key: keytool -genkeypair or importkeystore from a PKCS12 bundle containing key+cert
  3. Run keytool -list -v -keystore client.jks and confirm an entry of type PrivateKeyEntry exists
  4. Verify the store password is correct so the key entry is accessible

Example fix

// before (config)
// truststorePath: client-keystore.jks  <- wrong file
// after
// keystorePath: client-keystore.jks
// truststorePath: truststore.jks
Defensive patterns

Strategy: validation

Validate before calling

out, _ := exec.Command("keytool", "-list", "-keystore", keystorePath,
    "-storepass", password).Output()
if !strings.Contains(string(out), "PrivateKeyEntry") {
    return fmt.Errorf("%s is not a client keystore (no private key)", keystorePath)
}

Try / catch

tlsCert, err := buildTLSConfig(...)
if err != nil && strings.Contains(err.Error(), "no private key entry") {
    // verify keystore vs truststore config
}

Prevention

When it happens

Trigger: Calling buildTLSConfig/buildZooKeeperTLSConfig with a keystore that contains only TrustedCertEntry certificates (i.e., it is actually a truststore), or an empty/unsupported JKS entry type.

Common situations: Swapping truststore and keystore file paths in configuration; exporting a truststore from a server and using it as the client keystore; keystore rebuilt after JVM upgrade losing the key entry; wrong password hiding entries.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/89c9ee10c9a1a96a. Report an issue: GitHub.