t8y2/dbx · error

load ZooKeeper keystore: %w

Error message

load ZooKeeper keystore: %w

What it means

buildZooKeeperTLSConfig wraps any failure from loadClientKeyStore with "load ZooKeeper keystore: %w". loadClientKeyStore reads the zookeeperkeystorelocation file and extracts the private key + certificate chain for client (mTLS) authentication. Any read, decrypt, parse failure, or a keystore without a private key entry is reported here, meaning client TLS identity cannot be established.

Source

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

		)
		if err != nil {
			return nil, fmt.Errorf("load ZooKeeper truststore: %w", err)
		}
		pool := x509.NewCertPool()
		for _, certificate := range certificates {
			pool.AddCert(certificate)
		}
		config.RootCAs = pool
	}
	keyStoreLocation := parameter(values, "zookeeperkeystorelocation")
	if keyStoreLocation != "" {
		certificate, err := loadClientKeyStore(
			keyStoreLocation,
			parameter(values, "zookeeperkeystorepassword"),
			parameter(values, "zookeeperkeystoretype"),
		)
		if err != nil {
			return nil, fmt.Errorf("load ZooKeeper keystore: %w", err)
		}
		config.Certificates = []tls.Certificate{certificate}
	}
	if parameterBool(values, "zookeepersslinsecureskipverify") {
		config.InsecureSkipVerify = true
	}
	return config, nil
}

func loadTrustStore(path, password, storeType string) ([]*x509.Certificate, error) {
	contents, err := os.ReadFile(path)
	if err != nil {
		return nil, err
	}
	switch normalizedStoreType(storeType, path) {
	case "PEM":
		return parsePEMCertificates(contents)
	case "PKCS12":

View on GitHub (pinned to c0390bff16)

Solutions

  1. Verify zookeeperkeystorelocation points to an existing, readable keystore file.
  2. Confirm zookeeperkeystorepassword is the current keystore password.
  3. Re-export the keystore ensuring it contains a private key entry WITH its certificate chain.
  4. Set zookeeperkeystoretype to match the actual format (PEM, JKS, PKCS12).
  5. Check the wrapped underlying error to distinguish file-read vs parse/key-entry failures.

Example fix

// before
params.Set("zookeeperkeystorelocation", "client.jks") // JKS with cert only, no key
// after
// openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12
params.Set("zookeeperkeystorelocation", "/etc/certs/zk/client.p12")
params.Set("zookeeperkeystoretype", "PKCS12")
params.Set("zookeeperkeystorepassword", os.Getenv("ZK_KEYSTORE_PASSWORD"))
Defensive patterns

Strategy: validation

Validate before calling

path := params.Get("zookeeperkeystorelocation")
if path != "" {
    if fi, err := os.Stat(path); err != nil || fi.IsDir() {
        return fmt.Errorf("keystore not readable: %s", path)
    }
    if params.Get("zookeeperkeystorepassword") == "" {
        return fmt.Errorf("zookeeperkeystorepassword required for keystore %s", path)
    }
}

Try / catch

cfg, err := buildZooKeeperTLSConfig(values)
if err != nil && strings.Contains(err.Error(), "load ZooKeeper keystore") {
    return fmt.Errorf("mTLS client keystore unusable; verify file, password, and that it contains a private key with chain: %w", err)
}

Prevention

When it happens

Trigger: parseConnectionConfig builds TLS config with zookeeperkeystorelocation set: the keystore file is missing/unreadable, zookeeperkeystorepassword is wrong, zookeeperkeystoretype is unsupported, the JKS has no PrivateKey entry, or the entry has no certificate chain.

Common situations: mTLS setup where the client cert was issued without its chain; keystore password rotated out of band; PKCS12 exported from openssl without the key; wrong file mounted in Kubernetes secret; store type mismatch (PEM content labeled JKS).

Related errors


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