{"record":{"id":"c69fc16fc6c6282d","repo":"jaegertracing/jaeger","slug":"s-tls-options-cannot-be-used-when-s-is-false","errorCode":null,"errorMessage":"%s.tls.* options cannot be used when %s is false","messagePattern":"(.+?)\\.tls\\.\\* options cannot be used when (.+?) is false","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/tlscfg/flags.go","lineNumber":77,"sourceCode":"\tflags.String(c.Prefix+tlsMinVersion, \"\", \"Minimum TLS version supported (Possible values: 1.0, 1.1, 1.2, 1.3)\")\n\tflags.String(c.Prefix+tlsMaxVersion, \"\", \"Maximum TLS version supported (Possible values: 1.0, 1.1, 1.2, 1.3)\")\n\tflags.Duration(c.Prefix+tlsReloadInterval, 0, \"The duration after which the certificate will be reloaded (0s means will not be reloaded)\")\n}\n\n// InitFromViper creates tls.Config populated with values retrieved from Viper.\nfunc (c ClientFlagsConfig) InitFromViper(v *viper.Viper) (configtls.ClientConfig, error) {\n\tvar p options\n\tp.Enabled = v.GetBool(c.Prefix + tlsEnabled)\n\tp.CAPath = v.GetString(c.Prefix + tlsCA)\n\tp.CertPath = v.GetString(c.Prefix + tlsCert)\n\tp.KeyPath = v.GetString(c.Prefix + tlsKey)\n\tp.ServerName = v.GetString(c.Prefix + tlsServerName)\n\tp.SkipHostVerify = v.GetBool(c.Prefix + tlsSkipHostVerify)\n\n\tif !p.Enabled {\n\t\tvar empty options\n\t\tif !reflect.DeepEqual(&p, &empty) {\n\t\t\treturn configtls.ClientConfig{}, fmt.Errorf(\"%s.tls.* options cannot be used when %s is false\", c.Prefix, c.Prefix+tlsEnabled)\n\t\t}\n\t}\n\n\treturn p.ToOtelClientConfig(), nil\n}\n\n// InitFromViper creates tls.Config populated with values retrieved from Viper.\nfunc (c ServerFlagsConfig) InitFromViper(v *viper.Viper) (configoptional.Optional[configtls.ServerConfig], error) {\n\tvar p options\n\tp.Enabled = v.GetBool(c.Prefix + tlsEnabled)\n\tp.CertPath = v.GetString(c.Prefix + tlsCert)\n\tp.KeyPath = v.GetString(c.Prefix + tlsKey)\n\tp.ClientCAPath = v.GetString(c.Prefix + tlsClientCA)\n\tif s := v.GetString(c.Prefix + tlsCipherSuites); s != \"\" {\n\t\tp.CipherSuites = strings.Split(stripWhiteSpace(v.GetString(c.Prefix+tlsCipherSuites)), \",\")\n\t}\n\tp.MinVersion = v.GetString(c.Prefix + tlsMinVersion)\n\tp.MaxVersion = v.GetString(c.Prefix + tlsMaxVersion)","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/config/tlscfg/flags.go#L59-L95","documentation":"tlscfg.ClientFlagsConfig.InitFromViper builds a client TLS options struct from Viper settings. If tls.enabled is false but any other tls.* field was set, the struct differs from the zero value and the call fails, because TLS options are meaningless (and likely a mistake) when TLS is disabled. The reflect.DeepEqual against an empty options struct detects 'extra' TLS settings.","triggerScenarios":"Calling InitFromViper for a client prefix where <prefix>.tls.enabled is false/absent while one or more <prefix>.tls.* keys (ca, cert, key, server-name, skip-host-verify, etc.) are set in Viper.","commonSituations":"Disabling TLS by setting enabled: false but forgetting to remove the cert/key lines; a config template that always emits tls.* keys; leftover keys from a previous TLS setup in YAML or environment variables.","solutions":["Set <prefix>.tls.enabled: true if you actually want TLS","Remove all <prefix>.tls.* options other than enabled when TLS is disabled","Check Viper/env for stray keys like <prefix>.tls.skip-host-verify=true left from defaults","Inspect the merged Viper config (v.AllSettings()) to find which tls.* key is non-empty"],"exampleFix":"# before\nstorage.tls.enabled: false\nstorage.tls.skip-host-verify: true\n# after\nstorage.tls.enabled: false","handlingStrategy":"validation","validationCode":"if !tlsEnabled {\n    for k := range viper.AllSettings() {\n        if strings.HasPrefix(k, prefix+\".tls.\") && k != prefix+\".tls.enabled\" {\n            return fmt.Errorf(\"remove %s: tls is disabled\", k)\n        }\n    }\n}\nerr := tlscfg.ClientFlagsConfig{Prefix: prefix}.InitFromViper(v)","typeGuard":null,"tryCatchPattern":"if err := cfg.InitFromViper(v); err != nil {\n    if strings.Contains(err.Error(), \"cannot be used when\") {\n        // strip or fix tls.* keys, re-init\n    }\n    return err\n}","preventionTips":["When disabling TLS, delete all sibling tls.* options in the same change","Search config files for '.tls.' keys after flipping enabled to false","Prefer config templates that conditionally render the tls block","Test config loading in CI with both tls-enabled and tls-disabled fixtures"],"tags":["config","tls","validation"],"backgroundTag":"conflicting-tls-config","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}