temporalio/temporal · error
only one of caData or caFile properties should be specified
Error message
only one of caData or caFile properties should be specified
What it means
ConfigureCassandraCluster validates the Cassandra TLS config and rejects a config that specifies both inline CA certificate content (CaData) and a CA file path (CaFile). Only one CA source may be given so the SslOpts.RootCAs pool can be built deterministically. Thrown before any connection is attempted.
Source
Thrown at common/persistence/nosql/nosqlplugin/cassandra/gocql/client.go:69
}
}
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)
if err != nil {
return fmt.Errorf("error reading client certificate file: %w", err)
}
} else if cfg.TLS.CertData != "" {View on GitHub (pinned to bde624efd1)
Solutions
- Remove either caData or caFile from the cassandra TLS config, keeping only one
- Prefer caFile when certs are mounted on disk; set caData to ""
- Prefer caData (base64-encoded PEM) when config is delivered via dynamicconfig; delete caFile
Example fix
// before
persistence:
cassandra:
tls:
enabled: true
caFile: /etc/certs/ca.pem
caData: LS0tLS1CRUdJTiBDRVJUSUZ...
// after
persistence:
cassandra:
tls:
enabled: true
caData: LS0tLS1CRUdJTiBDRVJUSUZ...
Defensive patterns
Strategy: validation
Validate before calling
func validateTLSCA(tls config.TLS) error {
if !tls.Enabled { return nil }
if tls.CaData != "" && tls.CaFile != "" {
return errors.New("specify only one of caData or caFile")
}
return nil
} Prevention
- Standardize on caFile for mounted secrets or caData for dynamicconfig, not both
- Add a config lint step validating TLS fields before deploy
- When migrating between the two, explicitly delete the old field rather than leaving it populated
When it happens
Trigger: Calling NewCassandraCluster with cfg.TLS.Enabled true and both cfg.TLS.CaData and cfg.TLS.CaFile non-empty.
Common situations: Cluster operators migrating from file-based certs to inline dynamicconfig values without deleting the old field; helm charts templating both values; accidental duplication when overriding config per environment.
Related errors
- only one of keyData or keyFile properties should be specifie
- 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/2b377b18fb06ebde.
Report an issue: GitHub.