t8y2/dbx · error

both client_cert_path and client_key_path are required for I

Error message

both client_cert_path and client_key_path are required for IoTDB mTLS

What it means

parseConnectionConfig validates IoTDB mTLS settings and requires client_cert_path and client_key_path to be set together. If exactly one is provided, the config is incomplete and the driver rejects it.

Source

Thrown at agents/drivers/iotdb/driver.go:210

	if len(config.NodeURLs) == 0 {
		config.NodeURLs = []string{net.JoinHostPort(config.Host, strconv.Itoa(config.Port))}
	}

	tlsEnabled := params.SSL || queryBool(query, "ssl", "useSSL", "use_ssl", "tls")
	if tlsEnabled {
		config.TLSInsecureSkipVerify = queryBool(query, "insecure_skip_verify", "tls_insecure_skip_verify")
		config.TLSConfig = &client.TLSConfig{
			Config: &tls.Config{
				ServerName:         config.Host,
				MinVersion:         tls.VersionTLS12,
				InsecureSkipVerify: config.TLSInsecureSkipVerify,
			},
			CAFile:   strings.TrimSpace(params.CACertPath),
			CertFile: strings.TrimSpace(params.ClientCertPath),
			KeyFile:  strings.TrimSpace(params.ClientKeyPath),
		}
		if (config.TLSConfig.CertFile == "") != (config.TLSConfig.KeyFile == "") {
			return connectionConfig{}, errors.New("both client_cert_path and client_key_path are required for IoTDB mTLS")
		}
	}
	return config, nil
}

func newSessionClient(config connectionConfig) (*sessionClient, error) {
	var session client.Session
	var err error
	// DBX applies a table database with USE after switching dialects. Do not
	// include a tree database in openSession: IoTDB 2.x rejects it there, while
	// DBX still retains it for metadata and path qualification.
	if len(config.NodeURLs) > 1 {
		session, err = client.NewClusterSession(&client.ClusterConfig{
			NodeUrls:        config.NodeURLs,
			UserName:        config.Username,
			Password:        config.Password,
			FetchSize:       config.FetchSize,
			TimeZone:        config.TimeZone,

View on GitHub (pinned to c0390bff16)

Solutions

  1. Set both client_cert_path and client_key_path to valid PEM file paths in the connection parameters.
  2. If mTLS is not intended, remove the lone client_cert_path/client_key_path parameter so one-way TLS (CA only) is used.
  3. Print/inspect the parsed params (e.g. log config.TLSConfig) to confirm both fields resolve; check for typos like client_cert or clientkey_path.

Example fix

// before
params: ca_cert_path=/ca.pem client_cert_path=/client.crt
// after
params: ca_cert_path=/ca.pem client_cert_path=/client.crt client_key_path=/client.key
Defensive patterns

Strategy: validation

Validate before calling

func validateMTLSParams(params map[string]string) error {
	cert, key := params["client_cert_path"], params["client_key_path"]
	if (cert != "") != (key != "") {
		return errors.New("client_cert_path and client_key_path must be set together")
	}
	return nil
}

Type guard

func mTLSConfigComplete(tlsCfg TLSConfig) bool { return tlsCfg.CertFile != "" && tlsCfg.KeyFile != "" }

Try / catch

cfg, err := parseConnectionConfig(params)
if err != nil {
	if strings.Contains(err.Error(), "client_cert_path and client_key_path") {
		return fmt.Errorf("mTLS needs both files: set client_cert_path and client_key_path (got cert=%q key=%q)", params["client_cert_path"], params["client_key_path"])
	}
	return err
}

Prevention

When it happens

Trigger: Enabling TLS with only client_cert_path or only client_key_path set (after trimming whitespace); a typo in one of the two parameter names so only one resolves.

Common situations: Partial migration from one-way TLS to mTLS; config templates with placeholders filled inconsistently; misspelled key names in connection strings/env vars.

Related errors


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