{"record":{"id":"28cfaed2c6aa69cd","repo":"temporalio/temporal","slug":"cannot-specify-certfile-and-certdata-at-the-same-t","errorCode":null,"errorMessage":"cannot specify CertFile and CertData at the same time","messagePattern":"cannot specify CertFile and CertData at the same time","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/rpc/encryption/tls_factory.go","lineNumber":109,"sourceCode":"\t}\n\tif err := validateClientTLS(&cfg.Client); err != nil {\n\t\treturn err\n\t}\n\tfor host, hostConfig := range cfg.PerHostOverrides {\n\n\t\tif strings.TrimSpace(host) == \"\" {\n\t\t\treturn fmt.Errorf(\"host name cannot be empty string\")\n\t\t}\n\t\tif err := validateServerTLS(&hostConfig); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc validateWorkerTLS(cfg *config.WorkerTLS) error {\n\tif cfg.CertFile != \"\" && cfg.CertData != \"\" {\n\t\treturn fmt.Errorf(\"cannot specify CertFile and CertData at the same time\")\n\t}\n\tif cfg.KeyFile != \"\" && cfg.KeyData != \"\" {\n\t\treturn fmt.Errorf(\"cannot specify KeyFile and KeyData at the same time\")\n\t}\n\treturn validateClientTLS(&cfg.Client)\n}\n\nfunc validateServerTLS(cfg *config.ServerTLS) error {\n\tif cfg.CertFile != \"\" && cfg.CertData != \"\" {\n\t\treturn fmt.Errorf(\"cannot specify CertFile and CertData at the same time\")\n\t}\n\tif cfg.KeyFile != \"\" && cfg.KeyData != \"\" {\n\t\treturn fmt.Errorf(\"cannot specify KeyFile and KeyData at the same time\")\n\t}\n\tif err := validateCAs(cfg.ClientCAData); err != nil {\n\t\treturn fmt.Errorf(\"invalid ServerTLS.ClientCAData: %w\", err)\n\t}\n\tif err := validateCAs(cfg.ClientCAFiles); err != nil {","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/rpc/encryption/tls_factory.go#L91-L127","documentation":"validateWorkerTLS enforces that WorkerTLS config specifies a certificate either by file path (CertFile) or inline data (CertData), never both. Supplying both is ambiguous, so validation fails with this error before any TLS config is built. It is checked when validateRootTLS validates worker TLS settings.","triggerScenarios":"WorkerTLS block where both cfg.CertFile and cfg.CertData are non-empty — e.g. migrating from file-based to inline secrets while keeping the old path, or merging dynamic config layers that each set a different field.","commonSituations":"Setting certDataFile contents via secret injection while a legacy certFile line remains in the config; stacking multiple dynamic config YAMLs where one sets CertFile and another CertData.","solutions":["Remove one of the two: keep CertFile for on-disk certs or CertData for inline PEM, not both.","If both come from merged dynamic config layers, delete the obsolete field from the higher-precedence layer.","After fixing, ensure KeyFile/KeyData follow the same single-source rule."],"exampleFix":"// before\ncertFile: /etc/certs/client.pem\ncertData: |\n  -----BEGIN CERTIFICATE-----...\n// after\ncertFile: /etc/certs/client.pem   # certData removed","handlingStrategy":"validation","validationCode":"if cfg.CertFile != \"\" && cfg.CertData != \"\" {\n    return errors.New(\"worker TLS cert: set only one of CertFile/CertData\")\n}","typeGuard":null,"tryCatchPattern":"if err := validateWorkerTLS(&cfg.Global.WorkerTLS); err != nil {\n    return fmt.Errorf(\"worker TLS config invalid: %w\", err)\n}","preventionTips":["Standardize on one cert source (files or inline data) per environment.","Audit stacked dynamic config layers for duplicate fields.","Run validation in CI before shipping config."],"tags":["config","validation","tls","worker"],"backgroundTag":"tls-config-validation-failed","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}