router-for-me/CLIProxyAPI · error
home tls: read ca-cert: %w
Error message
home tls: read ca-cert: %w
What it means
Wraps os.ReadFile failure in internal/home/client.go when reading the configured CA certificate file for the home TLS root pool. The %w preserves the os error — almost always 'no such file or directory' or 'permission denied' for the ca-cert path.
Source
Thrown at internal/home/client.go:653
if clientCertPath != "" || clientKeyPath != "" {
if clientCertPath == "" || clientKeyPath == "" {
return nil, fmt.Errorf("home tls: client certificate and key must be set together")
}
certPair, errLoad := tls.LoadX509KeyPair(clientCertPath, clientKeyPath)
if errLoad != nil {
return nil, fmt.Errorf("home tls: load client certificate: %w", errLoad)
}
tlsConfig.Certificates = []tls.Certificate{certPair}
}
caCertPath := strings.TrimSpace(cfg.CACert)
if caCertPath == "" {
return tlsConfig, nil
}
caCertPEM, errRead := os.ReadFile(caCertPath)
if errRead != nil {
return nil, fmt.Errorf("home tls: read ca-cert: %w", errRead)
}
certPool, errPool := x509.SystemCertPool()
if errPool != nil || certPool == nil {
certPool = x509.NewCertPool()
}
if !certPool.AppendCertsFromPEM(caCertPEM) {
return nil, fmt.Errorf("home tls: ca-cert contains no PEM certificates")
}
tlsConfig.RootCAs = certPool
return tlsConfig, nil
}
func (c *Client) commandClient() (*redis.Client, error) {
if c == nil || c.dispatchFenced.Load() {
return nil, ErrDispatchFenced
}View on GitHub (pinned to 78f0c4079e)
Solutions
- Verify the exact path exists from the process's perspective: ls -l <path> as the service user
- Use absolute paths in config to avoid working-directory dependence
- Fix permissions (0644 readable) or ownership if it is a permission error
- If the CA was never copied, distribute it from the home server
Example fix
# before
home:
tls:
ca-cert: ca.pem # relative, breaks under systemd/container
# after
home:
tls:
ca-cert: /etc/cliproxy/ca.pem Defensive patterns
Strategy: validation
Validate before calling
if cfg.TLS.CACert != "" {
if _, err := os.Stat(cfg.TLS.CACert); err != nil {
return fmt.Errorf("home ca-cert %s not accessible: %w", cfg.TLS.CACert, err)
}
} Try / catch
if err != nil && errors.Is(err, fs.ErrNotExist) {
log.Errorf("ca-cert path %s missing — distribute CA or fix mount", cfg.TLS.CACert)
} Prevention
- Use absolute paths for all TLS material
- Make secret mounts mandatory (not optional) so missing mounts fail loudly at deploy
When it happens
Trigger: home.tls.ca-cert points at a path that does not exist at runtime, or exists but is not readable by the process user; relative path resolved against a different working directory in a container/service.
Common situations: CA not yet distributed to the node; path typo or changed mount point in Kubernetes (secret not mounted); service running with a different WORKDIR so a relative path breaks; file owned root-only.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- home ca fingerprint is required
- home tls: client certificate and key must be set together
- home ca fingerprint mismatch
- home ca certificate pem is invalid
- client key pem is invalid
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/00cdc538613b5143.
Report an issue: GitHub.