{"record":{"id":"1ce20c8010e6b0a8","repo":"temporalio/temporal","slug":"invalid-value-for-publicclient-forcetlsconfig-q","errorCode":null,"errorMessage":"invalid value for publicClient.forceTLSConfig: %q","messagePattern":"invalid value for publicClient\\.forceTLSConfig: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/config/config.go","lineNumber":712,"sourceCode":"// Validate validates this config\nfunc (c *Config) Validate() error {\n\tif err := c.Persistence.Validate(); err != nil {\n\t\treturn err\n\t}\n\n\tif err := c.Archival.Validate(&c.NamespaceDefaults.Archival); err != nil {\n\t\treturn err\n\t}\n\n\t_, hasIFE := c.Services[string(primitives.InternalFrontendService)]\n\tif hasIFE && (c.PublicClient.HostPort != \"\" || c.PublicClient.ForceTLSConfig != \"\" || c.PublicClient.HTTPHostPort != \"\") {\n\t\treturn fmt.Errorf(\"when using internal-frontend, publicClient must be empty\")\n\t}\n\n\tswitch c.PublicClient.ForceTLSConfig {\n\tcase ForceTLSConfigAuto, ForceTLSConfigInternode, ForceTLSConfigFrontend:\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid value for publicClient.forceTLSConfig: %q\", c.PublicClient.ForceTLSConfig)\n\t}\n\n\treturn nil\n}\n\n// String converts the config object into a string\nfunc (c *Config) String() string {\n\tvar buf bytes.Buffer\n\tencoder := yaml.NewEncoder(&buf)\n\tencoder.SetIndent(2)\n\t_ = encoder.Encode(c)\n\tmaskedYaml, _ := masker.MaskYaml(buf.String(), masker.DefaultYAMLFieldNames)\n\treturn maskedYaml\n}\n\nfunc (r *GroupTLS) IsServerEnabled() bool {\n\treturn r.Server.KeyFile != \"\" || r.Server.KeyData != \"\"\n}","sourceCodeStart":694,"sourceCodeEnd":730,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/config/config.go#L694-L730","documentation":"Config.Validate checks that publicClient.forceTLSConfig is one of the recognized enum values. If the string is anything other than the supported constants, validation fails with this error naming the offending value via %q. This guards against typo'd TLS enforcement modes silently disabling or misconfiguring TLS.","triggerScenarios":"Calling (Config).Validate when c.PublicClient.ForceTLSConfig is set to a string other than ForceTLSConfigAuto, ForceTLSConfigInternode, or ForceTLSConfigFrontend (e.g. \"auto \" with whitespace, \"true\", \"tls\").","commonSituations":"Typos in the YAML value (e.g. forceTLSConfig: Auto vs auto, or misspellings), copying config from an older temporal version where different values were accepted, or forgetting the field must be blank (empty) when not forcing TLS in deployments without internal-frontend.","solutions":["Set publicClient.forceTLSConfig to one of the exact supported values: auto, internode, or frontend (match the ForceTLSConfig* constant strings)","If unsure, remove the forceTLSConfig key entirely so it stays empty (allowed when no internal-frontend service is configured)","Check the constant definitions in common/config to confirm exact accepted strings"],"exampleFix":"// before\npublicClient:\n  forceTLSConfig: \"always\"\n// after\npublicClient:\n  forceTLSConfig: \"internode\"","handlingStrategy":"validation","validationCode":"switch strings.TrimSpace(cfg.PublicClient.ForceTLSConfig) {\ncase config.ForceTLSConfigAuto, config.ForceTLSConfigInternode, config.ForceTLSConfigFrontend, \"\":\n\t// ok\ndefault:\n\treturn fmt.Errorf(\"forceTLSConfig must be auto|internode|frontend, got %q\", cfg.PublicClient.ForceTLSConfig)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reference the ForceTLSConfig* constants in code instead of hardcoding strings","Never set forceTLSConfig unless you intend to force TLS; empty is valid","Lint YAML configs against a schema listing the allowed enum values"],"tags":["config","validation","tls"],"backgroundTag":"invalid-enum-config-value","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}