gastownhall/beads · error
ExternalDoltConfig: TLSCert %q is not absolute
Error message
ExternalDoltConfig: TLSCert %q is not absolute
What it means
ExternalDoltConfig.Validate requires TLSCert to be an absolute path when set. Client certificate files are read from disk during TLSClientConfig, and a relative path would depend on the process working directory, which is not guaranteed. This check runs at configuration validation time, before any connection is attempted.
Source
Thrown at internal/configfile/external_dolt_config.go:71
}
if hasHost && (c.Port < 1 || c.Port > 65535) {
return fmt.Errorf("ExternalDoltConfig: Port %d out of range [1, 65535]", c.Port)
}
if hasSocket && !filepath.IsAbs(c.Socket) {
return fmt.Errorf("ExternalDoltConfig: Socket %q is not absolute", c.Socket)
}
switch {
case c.TLSCert != "" && c.TLSKey == "":
return errors.New("ExternalDoltConfig: TLSCert set without TLSKey")
case c.TLSCert == "" && c.TLSKey != "":
return errors.New("ExternalDoltConfig: TLSKey set without TLSCert")
}
if c.TLSCert != "" && !filepath.IsAbs(c.TLSCert) {
return fmt.Errorf("ExternalDoltConfig: TLSCert %q is not absolute", c.TLSCert)
}
if c.TLSKey != "" && !filepath.IsAbs(c.TLSKey) {
return fmt.Errorf("ExternalDoltConfig: TLSKey %q is not absolute", c.TLSKey)
}
if c.TLSCACert != "" && !filepath.IsAbs(c.TLSCACert) {
return fmt.Errorf("ExternalDoltConfig: TLSCACert %q is not absolute", c.TLSCACert)
}
if !c.TLSRequired {
switch {
case c.TLSCACert != "":
return errors.New("ExternalDoltConfig: TLSCACert set without TLSRequired")
case c.TLSCert != "" || c.TLSKey != "":
return errors.New("ExternalDoltConfig: TLSCert/TLSKey set without TLSRequired")
case c.TLSServerName != "":
return errors.New("ExternalDoltConfig: TLSServerName set without TLSRequired")
case c.TLSSkipVerify:
return errors.New("ExternalDoltConfig: TLSSkipVerify set without TLSRequired")View on GitHub (pinned to 71377f2769)
Solutions
- Replace the TLSCert value with an absolute path, e.g. "/etc/beads/tls/client.pem".
- Expand "~/" and environment variables before writing them into the config.
- If mutual TLS is not needed, remove TLSCert (and TLSKey) entirely.
Example fix
// before tlsCert: "~/certs/client.pem" // after tlsCert: "/home/alice/certs/client.pem"
Defensive patterns
Strategy: validation
Validate before calling
func validTLSCert(cfg configfile.ExternalDoltConfig) error {
if cfg.TLSCert != "" && !filepath.IsAbs(cfg.TLSCert) {
return fmt.Errorf("TLSCert must be absolute: %q", cfg.TLSCert)
}
return nil
} Prevention
- Never write "~/" paths into configs — Go does not expand tilde
- Generate config values with a script that resolves absolute paths at write time
- Keep certs in a fixed absolute location like /etc/beads/tls/
When it happens
Trigger: Calling Validate (via NewExternalDoltServer, NewExternalDoltServerUOWProvider, or buildProxiedServerClientInfo) with TLSCert set to a relative path like "certs/client.pem" or an unexpanded "~/certs/client.pem" (tilde is not absolute in Go).
Common situations: Config written with "~/..." paths assuming shell-style expansion; config files shared across machines with different cert locations; running the tool from a directory different from where the config was authored.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- ExternalDoltConfig: TLSKey %q is not absolute
- ExternalDoltConfig: TLSCACert %q is not absolute
- ExternalDoltConfig: Socket %q is not absolute
- server: NewDoltServer: doltBinExec is required
- server: NewDoltServer: rootDir is required
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/b18419e92ecd63c3.
Report an issue: GitHub.