router-for-me/CLIProxyAPI · error

home tls: client certificate and key must be set together

Error message

home tls: client certificate and key must be set together

What it means

Returned by the TLS-config builder in internal/home/client.go when exactly one of client-cert / client-key is set (after trimming). mTLS requires the pair together; supplying only one is treated as a configuration error rather than silently skipping client certificates.

Source

Thrown at internal/home/client.go:637

		return nil, nil
	}

	serverName := strings.TrimSpace(cfg.ServerName)
	if serverName == "" {
		serverName = strings.TrimSpace(fallbackServerName)
	}

	tlsConfig := &tls.Config{
		MinVersion:         tls.VersionTLS12,
		ServerName:         serverName,
		InsecureSkipVerify: cfg.InsecureSkipVerify,
	}

	clientCertPath := strings.TrimSpace(cfg.ClientCert)
	clientKeyPath := strings.TrimSpace(cfg.ClientKey)
	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)
	}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Set both client-cert and client-key paths (or neither, if the server does not require mTLS)
  2. Check YAML indentation places both keys under the same home/tls block
  3. If using templating/secrets, assert both files exist before starting

Example fix

# before
home:
  tls:
    client-cert: /etc/cliproxy/client.pem

# after
home:
  tls:
    client-cert: /etc/cliproxy/client.pem
    client-key: /etc/cliproxy/client.key
Defensive patterns

Strategy: validation

Validate before calling

cert := strings.TrimSpace(cfg.TLS.ClientCert)
key := strings.TrimSpace(cfg.TLS.ClientKey)
if (cert == "") != (key == "") {
    return errors.New("client-cert and client-key must both be set, or both omitted")
}

Prevention

When it happens

Trigger: Config sets client-cert but not client-key, or vice versa; one path left as an empty string while the other is populated; YAML indentation puts one key outside the home block.

Common situations: Copy-paste of a partial mTLS example; key path commented out accidentally; a templating variable for the key rendered empty in one environment (e.g. Kubernetes secret with a missing key).

Understand the failure class

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/e5f7c5759442ab84. Report an issue: GitHub.