{"record":{"id":"805a876fc0bb5cf9","repo":"temporalio/temporal","slug":"host-name-cannot-be-empty-string","errorCode":null,"errorMessage":"host name cannot be empty string","messagePattern":"host name cannot be empty string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/rpc/encryption/tls_factory.go","lineNumber":98,"sourceCode":"\t\treturn err\n\t}\n\tif err := validateGroupTLS(&cfg.Frontend); err != nil {\n\t\treturn err\n\t}\n\treturn validateWorkerTLS(&cfg.SystemWorker)\n}\n\nfunc validateGroupTLS(cfg *config.GroupTLS) error {\n\tif err := validateServerTLS(&cfg.Server); err != nil {\n\t\treturn err\n\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","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/rpc/encryption/tls_factory.go#L80-L116","documentation":"validateGroupTLS iterates PerHostOverrides of the root TLS config and rejects any override whose host key is empty (or only whitespace). Host keys select per-host server TLS settings, so an empty name is ambiguous and invalid. Raised during validateRootTLS, i.e. during TLS config validation before any connection is made.","triggerScenarios":"Dynamic config front-end/client TLS blocks containing a PerHostOverrides entry with an empty string or whitespace-only key, e.g. \"frontend\": {\"\": {...}} produced by templating or YAML parsing quirks.","commonSituations":"Dynamic config templates leaving a host placeholder unfilled; YAML merging producing an empty key; copy-pasted override entry where the host name was accidentally deleted.","solutions":["Find the PerHostOverrides entry with an empty/blank host key in your dynamic config and give it a valid host name or IP.","Remove the empty entry if it was accidental.","Check config templating/expansion output for unresolved placeholders.","Validate the config offline before applying it to the cluster."],"exampleFix":"// before\n\"frontend\": {\"PerHostOverrides\": {\"\": {\"serverName\": \"x\"}}}\n// after\n\"frontend\": {\"PerHostOverrides\": {\"temporal.internal:7233\": {\"serverName\": \"x\"}}}","handlingStrategy":"validation","validationCode":"for host := range cfg.PerHostOverrides {\n    if strings.TrimSpace(host) == \"\" {\n        return errors.New(\"PerHostOverrides contains an empty host key\")\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := validateGroupTLS(&cfg.Frontend); err != nil {\n    return fmt.Errorf(\"invalid frontend TLS config: %w\", err)\n}","preventionTips":["Render and inspect templated dynamic config before applying.","Lint dynamic config JSON/YAML for empty keys.","Test config changes on a staging cluster first."],"tags":["config","validation","tls"],"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"}