gastownhall/beads · error

ExternalDoltConfig: TLSRequired over Socket needs TLSServerN

Error message

ExternalDoltConfig: TLSRequired over Socket needs TLSServerName or TLSSkipVerify

What it means

When TLSRequired is set and the connection uses a Unix Socket, there is no hostname to use for TLS server-name verification, so the config must supply either TLSServerName (explicit SNI name) or TLSSkipVerify (explicit opt-out). Without one, certificate verification over a socket is impossible and the validator fails the config rather than producing a TLS client that can never verify the peer.

Source

Thrown at internal/configfile/external_dolt_config.go:94

	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")
		}
	}

	if c.TLSRequired && hasSocket && c.TLSServerName == "" && !c.TLSSkipVerify {
		return errors.New("ExternalDoltConfig: TLSRequired over Socket needs TLSServerName or TLSSkipVerify")
	}

	if c.KeepAlivePeriod < 0 {
		return fmt.Errorf("ExternalDoltConfig: KeepAlivePeriod %s is negative", c.KeepAlivePeriod)
	}

	return nil
}

func (c ExternalDoltConfig) TLSClientConfig() (*tls.Config, error) {
	if !c.TLSRequired {
		return nil, nil
	}

	cfg := &tls.Config{MinVersion: tls.VersionTLS12}

	if c.TLSSkipVerify {
		cfg.InsecureSkipVerify = true //nolint:gosec // G402: opt-in insecure transport via the TLSSkipVerify testing flag

View on GitHub (pinned to 71377f2769)

Solutions

  1. Add TLSServerName set to the name in the server certificate (correct fix).
  2. Set TLSSkipVerify: true for local/test sockets where verification is impractical (insecure; avoid in production).
  3. Switch back to Host/Port transport if the remote server's certificate should be verified against its real hostname.

Example fix

// before (YAML)
external:
  socket: /run/dolt/dolt.sock
  tls_required: true
// after
external:
  socket: /run/dolt/dolt.sock
  tls_required: true
  tls_server_name: dolt.local
  tls_ca_cert: /etc/beads/ca.pem
Defensive patterns

Strategy: validation

Validate before calling

func validateSocketTLS(cfg configfile.ExternalDoltConfig) error {
	if cfg.Socket != "" && cfg.TLSRequired && cfg.TLSServerName == "" && !cfg.TLSSkipVerify {
		return fmt.Errorf("TLS over socket %q needs tls_server_name or tls_skip_verify", cfg.Socket)
	}
	return cfg.Validate()
}

Try / catch

if err := cfg.Validate(); err != nil {
	if strings.Contains(err.Error(), "TLSRequired over Socket needs") {
		// add tls_server_name (or tls_skip_verify for local dev), then retry
	}
	return err
}

Prevention

When it happens

Trigger: Constructing ExternalDoltConfig with Socket set to an absolute path plus TLSRequired=true, but leaving TLSServerName empty and TLSSkipVerify false; Validate() (or NewExternalDoltServer / buildProxiedServerClientInfo / NewExternalDoltServerUOWProvider) rejects the combination.

Common situations: Migrating a TCP+TLS config to a local socket connection (e.g. sidecar deployment) and keeping tls_required: true; enabling TLS on a socket-based external Dolt server without realizing sockets have no hostname for cert verification.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/789b0e83eafa22a9. Report an issue: GitHub.