t8y2/dbx · error

load ZooKeeper truststore: %w

Error message

load ZooKeeper truststore: %w

What it means

buildZooKeeperTLSConfig loads a client trust store (JKS/PKCS12/etc.) via loadTrustStore using the connection-string parameters zookeepertruststorepassword and zookeepertruststoretype. If the store can't be read or decrypted (missing file, wrong password, unsupported type, bad format), the underlying error is wrapped as 'load ZooKeeper truststore: ...'. The client refuses to build a TLS config without a valid trust store.

Source

Thrown at agents/drivers/hive-go/zookeeper_tls.go:34

)

func buildZooKeeperTLSConfig(values map[string]string) (*tls.Config, error) {
	if !parameterBool(values, "zookeepersslenable") {
		return nil, nil
	}
	config := &tls.Config{
		MinVersion: tls.VersionTLS12,
		ServerName: parameter(values, "zookeeperservername"),
	}
	trustStoreLocation := parameter(values, "zookeepertruststorelocation")
	if trustStoreLocation != "" {
		certificates, err := loadTrustStore(
			trustStoreLocation,
			parameter(values, "zookeepertruststorepassword"),
			parameter(values, "zookeepertruststoretype"),
		)
		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}

View on GitHub (pinned to c0390bff16)

Solutions

  1. Verify the truststore file exists at trustStoreLocation from the perspective of the running process (absolute path or correct working dir).
  2. Confirm zookeepertruststorepassword matches the store's actual password (keytool -list or a PKCS12 check).
  3. Set zookeepertruststoretype correctly (JKS vs PKCS12) to match the file's real format.
  4. Re-export the trust store from the cluster's CA certificates if the file is corrupt or stale.
  5. Run the reference path TestBuildZooKeeperTLSConfigFromJKS/PKCS12 to confirm the loading code works with your store before deploying.

Example fix

// before
conn := "zk+tls://zk1:2181?truststore=/etc/certs/zk.ts&truststoretype=JKS" // file is actually PKCS12
// after
conn := "zk+tls://zk1:2181?truststore=/etc/certs/zk.p12&truststoretype=PKCS12&truststorepassword=s3cret"
Defensive patterns

Strategy: validation

Validate before calling

// validate the trust store before building the connection string
func validateTrustStore(path, password, storeType string) error {
	if _, err := os.Stat(path); err != nil {
		return fmt.Errorf("truststore not readable at %s: %w", path, err)
	}
	f, err := os.Open(path)
	if err != nil { return err }
	defer f.Close()
	switch strings.ToUpper(storeType) {
	case "PKCS12":
		if _, err := pkcs12.ToTrustPool(f, password); err != nil {
			return fmt.Errorf("pkcs12 open failed (password/format?): %w", err)
		}
	case "JKS":
		if _, err := jks.Decode(f, []byte(password)); err != nil {
			return fmt.Errorf("jks open failed (password/type?): %w", err)
		}
	default:
		return fmt.Errorf("unsupported truststore type %q", storeType)
	}
	return nil
}

Type guard

func isTrustStoreLoadError(err error) bool {
	return err != nil && strings.Contains(err.Error(), "load ZooKeeper truststore")
}

Try / catch

cfg, err := hive.ParseConnectionConfig(connStr)
if err != nil {
	if isTrustStoreLoadError(err) {
		// fail fast at startup with a precise message including the wrapped cause
		log.Fatalf("ZooKeeper TLS misconfigured: %v", err)
	}
	return err
}

Prevention

When it happens

Trigger: parseConnectionConfig with a TLS-enabled ZooKeeper connection string when trustStoreLocation is set but loadTrustStore fails: file path doesn't exist, wrong zookeepertruststorepassword, wrong/missing zookeepertruststoretype, or the file isn't a valid JKS/PKCS12 store.

Common situations: Truststore path wrong relative to the process working directory (works locally, fails in a container), password rotated in the secrets manager but not in the connection string, store exported as PKCS12 but type left as JKS, or the file never got mounted into the pod.

Related errors


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