temporalio/temporal · error
only one of keyData or keyFile properties should be specifie
Error message
only one of keyData or keyFile properties should be specified
What it means
ConfigureCassandraCluster validates the TLS block of the Cassandra config before building a gocql cluster config. It rejects configs where both inline cert content (KeyData) and a file path (KeyFile) are provided for the client private key, since the loader cannot decide which source to use. This is a fail-fast config sanity check.
Source
Thrown at common/persistence/nosql/nosqlplugin/cassandra/gocql/client.go:65
cluster.Authenticator = gocql.PasswordAuthenticator{
Username: cfg.User,
Password: cfg.Password,
AllowedAuthenticators: cfg.AllowedAuthenticators,
}
}
if cfg.Keyspace != "" {
cluster.Keyspace = cfg.Keyspace
}
if cfg.Datacenter != "" {
cluster.HostFilter = gocql.DataCentreHostFilter(cfg.Datacenter)
}
if cfg.TLS != nil && cfg.TLS.Enabled {
if cfg.TLS.CertData != "" && cfg.TLS.CertFile != "" {
return errors.New("only one of certData or certFile properties should be specified")
}
if cfg.TLS.KeyData != "" && cfg.TLS.KeyFile != "" {
return errors.New("only one of keyData or keyFile properties should be specified")
}
if cfg.TLS.CaData != "" && cfg.TLS.CaFile != "" {
return errors.New("only one of caData or caFile properties should be specified")
}
cluster.SslOpts = &gocql.SslOptions{
CaPath: cfg.TLS.CaFile,
EnableHostVerification: cfg.TLS.EnableHostVerification,
Config: auth.NewTLSConfigForServer(cfg.TLS.ServerName, cfg.TLS.EnableHostVerification),
}
var certBytes []byte
var keyBytes []byte
var err error
if cfg.TLS.CertFile != "" {
certBytes, err = os.ReadFile(cfg.TLS.CertFile)View on GitHub (pinned to bde624efd1)
Solutions
- Remove either the keyData or the keyFile property from the cassandra TLS config, keeping only one
- If using file-based secrets (common in k8s), set keyFile and clear keyData to ""
- If injecting the key inline (e.g. base64 in dynamic config), set keyData and remove keyFile
Example fix
// before
persistence:
cassandra:
tls:
enabled: true
keyFile: /etc/certs/key.pem
keyData: LS0tLS1CRUdJTi...
// after
persistence:
cassandra:
tls:
enabled: true
keyFile: /etc/certs/key.pem
Defensive patterns
Strategy: validation
Validate before calling
func validateTLSKey(tls config.TLS) error {
if !tls.Enabled { return nil }
if tls.KeyData != "" && tls.KeyFile != "" {
return errors.New("specify only one of keyData or keyFile")
}
return nil
} Prevention
- Pick one delivery mechanism (files vs inline data) per deployment and template only that field
- Assert in CI that rendered config has at most one of keyData/keyFile set
- Default the unused field to empty string in your config layering code
When it happens
Trigger: Calling NewCassandraCluster (via ConfigureCassandraCluster) with persistence config where cfg.TLS.Enabled is true and both cfg.TLS.KeyData and cfg.TLS.KeyFile are non-empty strings.
Common situations: Environment templating that injects both a base64 key and a mounted secret file path; copying an example config and filling in both fields; k8s operators setting KeyData while a sidecar already set KeyFile.
Related errors
- only one of caData or caFile properties should be specified
- only one of certData or certFile properties should be specif
- failed to load decoded CA Cert as PEM
- there is no addressTranslator configuration in cassandra con
- there are no options for translator plugin
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/9b88f52a7ea8ba44.
Report an issue: GitHub.