{"record":{"id":"9b88f52a7ea8ba44","repo":"temporalio/temporal","slug":"only-one-of-keydata-or-keyfile-properties-should-b","errorCode":null,"errorMessage":"only one of keyData or keyFile properties should be specified","messagePattern":"only one of keyData or keyFile properties should be specified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/persistence/nosql/nosqlplugin/cassandra/gocql/client.go","lineNumber":65,"sourceCode":"\t\tcluster.Authenticator = gocql.PasswordAuthenticator{\n\t\t\tUsername:              cfg.User,\n\t\t\tPassword:              cfg.Password,\n\t\t\tAllowedAuthenticators: cfg.AllowedAuthenticators,\n\t\t}\n\t}\n\tif cfg.Keyspace != \"\" {\n\t\tcluster.Keyspace = cfg.Keyspace\n\t}\n\tif cfg.Datacenter != \"\" {\n\t\tcluster.HostFilter = gocql.DataCentreHostFilter(cfg.Datacenter)\n\t}\n\tif cfg.TLS != nil && cfg.TLS.Enabled {\n\t\tif cfg.TLS.CertData != \"\" && cfg.TLS.CertFile != \"\" {\n\t\t\treturn errors.New(\"only one of certData or certFile properties should be specified\")\n\t\t}\n\n\t\tif cfg.TLS.KeyData != \"\" && cfg.TLS.KeyFile != \"\" {\n\t\t\treturn errors.New(\"only one of keyData or keyFile properties should be specified\")\n\t\t}\n\n\t\tif cfg.TLS.CaData != \"\" && cfg.TLS.CaFile != \"\" {\n\t\t\treturn errors.New(\"only one of caData or caFile properties should be specified\")\n\t\t}\n\n\t\tcluster.SslOpts = &gocql.SslOptions{\n\t\t\tCaPath:                 cfg.TLS.CaFile,\n\t\t\tEnableHostVerification: cfg.TLS.EnableHostVerification,\n\t\t\tConfig:                 auth.NewTLSConfigForServer(cfg.TLS.ServerName, cfg.TLS.EnableHostVerification),\n\t\t}\n\n\t\tvar certBytes []byte\n\t\tvar keyBytes []byte\n\t\tvar err error\n\n\t\tif cfg.TLS.CertFile != \"\" {\n\t\t\tcertBytes, err = os.ReadFile(cfg.TLS.CertFile)","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/persistence/nosql/nosqlplugin/cassandra/gocql/client.go#L47-L83","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\npersistence:\n  cassandra:\n    tls:\n      enabled: true\n      keyFile: /etc/certs/key.pem\n      keyData: LS0tLS1CRUdJTi...\n// after\npersistence:\n  cassandra:\n    tls:\n      enabled: true\n      keyFile: /etc/certs/key.pem\n","handlingStrategy":"validation","validationCode":"func validateTLSKey(tls config.TLS) error {\n    if !tls.Enabled { return nil }\n    if tls.KeyData != \"\" && tls.KeyFile != \"\" {\n        return errors.New(\"specify only one of keyData or keyFile\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["cassandra","tls","configuration"],"backgroundTag":"mutually-exclusive-config-options","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}