temporalio/temporal · error
only one of certData or certFile properties should be specif
Error message
only one of certData or certFile properties should be specified
What it means
This error is raised in ConfigureCassandraCluster (common/persistence/nosql/nosqlplugin/cassandra/gocql/client.go:61) when Cassandra TLS is enabled and the config specifies BOTH certData (inline PEM) and certFile (file path) for the client certificate. The plugin cannot choose between the two mutually exclusive sources, so cluster configuration fails immediately at startup rather than silently picking one. A sibling check enforces the same exclusivity for keyData/keyFile.
Source
Thrown at common/persistence/nosql/nosqlplugin/cassandra/gocql/client.go:61
if cfg.Port > 0 {
cluster.Port = cfg.Port
}
if cfg.User != "" && cfg.Password != "" {
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 []byteView on GitHub (pinned to bde624efd1)
Solutions
- Remove one of the two: keep only certFile (path-based) or only certData (inline), not both
- Do the same for keyData/keyFile, which the adjacent check enforces identically
- Audit config layering (base YAML + env overrides + secrets injection) to find where the duplicate TLS source enters
- Restart the service after cleaning the config; the error only appears at cluster-configuration time
Example fix
// before (config YAML)
tls:
enabled: true
certFile: /etc/certs/client.pem
certData: |
-----BEGIN CERTIFICATE-----
...
// after
tls:
enabled: true
certFile: /etc/certs/client.pem
keyFile: /etc/certs/client.key Defensive patterns
Strategy: validation
Validate before calling
tlsCfg := cfg.TLS
if tlsCfg != nil && tlsCfg.Enabled {
if tlsCfg.CertData != "" && tlsCfg.CertFile != "" {
return errors.New("specify only one of certData or certFile")
}
if tlsCfg.KeyData != "" && tlsCfg.KeyFile != "" {
return errors.New("specify only one of keyData or keyFile")
}
}
// safe: ConfigureCassandraCluster will accept TLS config Prevention
- Pick one TLS source convention per deployment: file paths OR inline PEM, never both
- Audit config layering (templates + env + secrets injection) so overrides do not add a second cert source
- Add a startup config linter/validator that rejects both fields set before persistence init
- Keep keyData/keyFile symmetric with your cert choice; the same exclusivity applies
When it happens
Trigger: Starting a server or store with Cassandra config where persistenceDataStores.cassandra.tls.enabled=true and both tls.certData and tls.certFile are non-empty (or both keyData and keyFile, per the adjacent check).
Common situations: Merging config from a template plus environment/overrides where one source sets certData and another sets certFile; copy-pasting an example config that included both fields; secrets tooling injecting inline certs while a legacy file path remains in the YAML.
Related errors
- unable to decode cassandra serial consistency: %v
- only one of keyData or keyFile properties should be specifie
- only one of caData or caFile properties should be specified
- failed to load decoded CA Cert as PEM
- only one of certData or certFile properties should be specif
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/356d8faf9e147870.
Report an issue: GitHub.