gastownhall/beads · error
ExternalDoltConfig: load client cert/key: %w
Error message
ExternalDoltConfig: load client cert/key: %w
What it means
TLSClientConfig failed to load the client certificate/key pair via tls.LoadX509KeyPair and wraps the underlying error. Common wrapped causes: file not found, permission denied, malformed PEM, or the cert and key not matching (different public keys). This is required when mutual TLS is configured with TLSCert set.
Source
Thrown at internal/configfile/external_dolt_config.go:136
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
- Confirm both files exist and are readable: ls -l <cert> <key>; fix permissions (chmod 600 on the key, correct owner).
- Verify cert and key match: compare `openssl x509 -noout -modulus` and `openssl rsa -noout -modulus` (or pub keys) — re-pair them if different.
- Ensure each file contains valid PEM blocks and TLSCert/TLSKey are not swapped.
- Remove TLSCert/TLSKey if mutual TLS is not actually required by the server.
Example fix
// before tlsCert: "/etc/beads/tls/client-new.pem" // renewed cert tlsKey: "/etc/beads/tls/client-old.key" // stale key -> mismatch // after tlsCert: "/etc/beads/tls/client-new.pem" tlsKey: "/etc/beads/tls/client-new.key"
Defensive patterns
Strategy: try-catch
Validate before calling
if cfg.TLSCert != "" && cfg.TLSKey != "" {
if _, err := tls.LoadX509KeyPair(cfg.TLSCert, cfg.TLSKey); err != nil {
return fmt.Errorf("client keypair precheck failed: %w", err)
}
} Try / catch
cfg, err := extCfg.TLSClientConfig()
if err != nil && strings.Contains(err.Error(), "load client cert/key") {
log.Fatalf("mTLS keypair bad (missing/unreadable/mismatched?): %v\nverify with: openssl x509 -noout -modulus <cert> && openssl rsa -noout -modulus <key>", err)
} Prevention
- Renew cert and key together, atomically
- chmod 600 private keys and ensure the service user owns them
- Verify cert/key match after any rotation before restarting services
When it happens
Trigger: Calling registerExternalTLSConfig -> TLSClientConfig with TLSCert/TLSKey paths pointing to missing files, unreadable keys, non-PEM content, or mismatched cert/key files.
Common situations: Key deployed without read permission for the service user; cert renewed but key not (or vice versa) causing mismatch; cert copied without its key; files swapped (key in TLSCert field); encrypted key with passphrase not supported by LoadX509KeyPair.
Related errors
- ExternalDoltConfig: read TLSCACert: %w
- ExternalDoltConfig: TLSCACert %q: no certificates parsed
- ExternalDoltConfig: TLSCert/TLSKey set without TLSRequired
- ExternalDoltConfig: TLSServerName set without TLSRequired
- ExternalDoltConfig: TLSSkipVerify set without TLSRequired
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/97b96bff0eed1d13.
Report an issue: GitHub.