{"record":{"id":"7793b3917d20cc9e","repo":"gastownhall/beads","slug":"externaldoltconfig-tlsservername-set-without-tlsr","errorCode":null,"errorMessage":"ExternalDoltConfig: TLSServerName set without TLSRequired","messagePattern":"ExternalDoltConfig: TLSServerName set without TLSRequired","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/configfile/external_dolt_config.go","lineNumber":87,"sourceCode":"\n\tif c.TLSCert != \"\" && !filepath.IsAbs(c.TLSCert) {\n\t\treturn fmt.Errorf(\"ExternalDoltConfig: TLSCert %q is not absolute\", c.TLSCert)\n\t}\n\tif c.TLSKey != \"\" && !filepath.IsAbs(c.TLSKey) {\n\t\treturn fmt.Errorf(\"ExternalDoltConfig: TLSKey %q is not absolute\", c.TLSKey)\n\t}\n\tif c.TLSCACert != \"\" && !filepath.IsAbs(c.TLSCACert) {\n\t\treturn fmt.Errorf(\"ExternalDoltConfig: TLSCACert %q is not absolute\", c.TLSCACert)\n\t}\n\n\tif !c.TLSRequired {\n\t\tswitch {\n\t\tcase c.TLSCACert != \"\":\n\t\t\treturn errors.New(\"ExternalDoltConfig: TLSCACert set without TLSRequired\")\n\t\tcase c.TLSCert != \"\" || c.TLSKey != \"\":\n\t\t\treturn errors.New(\"ExternalDoltConfig: TLSCert/TLSKey set without TLSRequired\")\n\t\tcase c.TLSServerName != \"\":\n\t\t\treturn errors.New(\"ExternalDoltConfig: TLSServerName set without TLSRequired\")\n\t\tcase c.TLSSkipVerify:\n\t\t\treturn errors.New(\"ExternalDoltConfig: TLSSkipVerify set without TLSRequired\")\n\t\t}\n\t}\n\n\tif c.TLSRequired && hasSocket && c.TLSServerName == \"\" && !c.TLSSkipVerify {\n\t\treturn errors.New(\"ExternalDoltConfig: TLSRequired over Socket needs TLSServerName or TLSSkipVerify\")\n\t}\n\n\tif c.KeepAlivePeriod < 0 {\n\t\treturn fmt.Errorf(\"ExternalDoltConfig: KeepAlivePeriod %s is negative\", c.KeepAlivePeriod)\n\t}\n\n\treturn nil\n}\n\nfunc (c ExternalDoltConfig) TLSClientConfig() (*tls.Config, error) {\n\tif !c.TLSRequired {","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/configfile/external_dolt_config.go#L69-L105","documentation":"Validate() requires that TLSServerName is only set when TLSRequired=true. TLSServerName overrides the SNI/hostname used for certificate verification; without TLSRequired the connection is plaintext and TLSClientConfig() returns nil, so TLSServerName would have no effect. The validator rejects the inert field rather than silently dropping it.","triggerScenarios":"Constructing ExternalDoltConfig with TLSServerName set (e.g. tls_server_name in the generated YAML) but TLSRequired false, then calling Validate() directly or via buildProxiedServerClientInfo / NewExternalDoltServer / NewExternalDoltServerUOWProvider.","commonSituations":"Connecting through a proxy/load-balancer where the cert's CN differs from the dial host, so the operator adds tls_server_name but forgets to enable tls_required; leftover server-name setting after TLS was disabled during incident debugging.","solutions":["Set TLSRequired: true so the SNI/ServerName override is actually applied.","Delete the TLSServerName field if the connection is intentionally plaintext.","Confirm the endpoint is actually serving TLS and re-enable the full TLS block together (tls_required + ca_cert/server_name)."],"exampleFix":"// before\nExternalDoltConfig{Host: \"db\", Port: 3307, TLSServerName: \"dolt.prod.internal\"}\n// after\nExternalDoltConfig{Host: \"db\", Port: 3307, TLSRequired: true, TLSServerName: \"dolt.prod.internal\", TLSCACert: \"/etc/beads/ca.pem\"}","handlingStrategy":"validation","validationCode":"func validateServerName(cfg configfile.ExternalDoltConfig) error {\n\tif cfg.TLSServerName != \"\" && !cfg.TLSRequired {\n\t\treturn fmt.Errorf(\"tls_server_name requires tls_required: true\")\n\t}\n\treturn cfg.Validate()\n}","typeGuard":null,"tryCatchPattern":"if err := cfg.Validate(); err != nil {\n\tif strings.Contains(err.Error(), \"TLSServerName set without TLSRequired\") {\n\t\t// enable tls_required or remove tls_server_name, then retry\n\t}\n\treturn err\n}","preventionTips":["Group tls_server_name with tls_required in any config-generation code or Helm chart.","Add a preflight Validate() call in deployment tooling so the contradiction surfaces before server start.","When disabling TLS for debugging, remove the whole TLS block, not just tls_required."],"tags":["tls","sni","config-validation","external-dolt"],"backgroundTag":"tls-config-mismatch","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}