gastownhall/beads · error

ExternalDoltConfig: read TLSCACert: %w

Error message

ExternalDoltConfig: read TLSCACert: %w

What it means

TLSClientConfig failed to read the TLSCACert file from disk and wraps the underlying os.ReadFile error. This happens after validation passed (path was absolute) but the file is missing, unreadable, or is a directory. The CA bundle is required to build the x509 root pool for verifying the external Dolt server.

Source

Thrown at internal/configfile/external_dolt_config.go:124

		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
	} else {
		name := c.TLSServerName
		if name == "" {
			name = c.Host
		}
		cfg.ServerName = name
	}

	if c.TLSCACert != "" {
		pem, err := os.ReadFile(c.TLSCACert)
		if err != nil {
			return nil, fmt.Errorf("ExternalDoltConfig: read TLSCACert: %w", err)
		}
		pool := x509.NewCertPool()
		if !pool.AppendCertsFromPEM(pem) {
			return nil, fmt.Errorf("ExternalDoltConfig: TLSCACert %q: no certificates parsed", c.TLSCACert)
		}
		cfg.RootCAs = pool
	}

	if c.TLSCert != "" {
		crt, err := tls.LoadX509KeyPair(c.TLSCert, c.TLSKey)
		if err != nil {
			return nil, fmt.Errorf("ExternalDoltConfig: load client cert/key: %w", err)
		}
		cfg.Certificates = []tls.Certificate{crt}
	}

	return cfg, nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Verify the file exists at the exact TLSCACert path (ls -l) and fix the path if it was moved.
  2. Fix permissions: chmod/chown so the running user can read the file, or run under an account with access.
  3. Provision the CA file on this machine (copy it or re-run your cert deployment).
  4. If the wrapped error is 'is a directory', point TLSCACert at the PEM file itself.

Example fix

// before
tlsCACert: "/etc/beads/tls/ca.pem"   // file missing
// after
# cp ca.pem /etc/beads/tls/ca.pem && chmod 644 /etc/beads/tls/ca.pem
tlsCACert: "/etc/beads/tls/ca.pem"
Defensive patterns

Strategy: try-catch

Validate before calling

if cfg.TLSCACert != "" {
    if _, err := os.Stat(cfg.TLSCACert); err != nil {
        return fmt.Errorf("CA cert not accessible: %w", err)
    }
}

Try / catch

cfg, err := extCfg.TLSClientConfig()
if err != nil {
    var perr *fs.PathError
    if errors.As(err, &perr) {
        log.Fatalf("CA cert unreadable at %s: %v — fix path/permissions", perr.Path, perr.Err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling registerExternalTLSConfig -> TLSClientConfig with TLSCACert pointing to a path that does not exist, has wrong permissions, or is a directory.

Common situations: Cert not deployed/provisioned on this machine; file deleted or rotated by cert management; path correct on another host; running as a user lacking read permission; SELinux/AppArmor blocking access.

Related errors


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