{"record":{"id":"8e4ecb4c2eefd259","repo":"gastownhall/beads","slug":"externaldoltconfig-tlskey-q-is-not-absolute","errorCode":null,"errorMessage":"ExternalDoltConfig: TLSKey %q is not absolute","messagePattern":"ExternalDoltConfig: TLSKey %q is not absolute","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/configfile/external_dolt_config.go","lineNumber":74,"sourceCode":"\t\treturn fmt.Errorf(\"ExternalDoltConfig: Port %d out of range [1, 65535]\", c.Port)\n\t}\n\n\tif hasSocket && !filepath.IsAbs(c.Socket) {\n\t\treturn fmt.Errorf(\"ExternalDoltConfig: Socket %q is not absolute\", c.Socket)\n\t}\n\n\tswitch {\n\tcase c.TLSCert != \"\" && c.TLSKey == \"\":\n\t\treturn errors.New(\"ExternalDoltConfig: TLSCert set without TLSKey\")\n\tcase c.TLSCert == \"\" && c.TLSKey != \"\":\n\t\treturn errors.New(\"ExternalDoltConfig: TLSKey set without TLSCert\")\n\t}\n\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","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/configfile/external_dolt_config.go#L56-L92","documentation":"ExternalDoltConfig.Validate requires TLSKey to be an absolute path when set. The private key file is loaded together with TLSCert via tls.LoadX509KeyPair in TLSClientConfig; a relative path would resolve against the current working directory and break unpredictably. Validation fails fast before any connection is made.","triggerScenarios":"Calling Validate (via NewExternalDoltServer, NewExternalDoltServerUOWProvider, or buildProxiedServerClientInfo) with TLSKey set to a relative path such as \"certs/client.key\" or an unexpanded \"~/certs/client.key\".","commonSituations":"Same as TLSCert: tilde paths that Go does not expand, configs copied between machines, or running the binary from a different working directory than intended.","solutions":["Set TLSKey to an absolute path, e.g. \"/etc/beads/tls/client.key\".","Expand \"~/\" and $VARS before storing the value in config.","If client cert auth is not required, clear both TLSCert and TLSKey."],"exampleFix":"// before\ntlsKey: \"certs/client.key\"\n// after\ntlsKey: \"/etc/beads/tls/client.key\"","handlingStrategy":"validation","validationCode":"func validTLSKey(cfg configfile.ExternalDoltConfig) error {\n    if cfg.TLSKey != \"\" && !filepath.IsAbs(cfg.TLSKey) {\n        return fmt.Errorf(\"TLSKey must be absolute: %q\", cfg.TLSKey)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use absolute paths for private keys in all environments","Expand environment variables before writing config","Always set TLSKey and TLSCert together from one templated block"],"tags":["config","validation","tls","path"],"backgroundTag":"invalid-config-value","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}