thanos-io/thanos · error

client cert file specified without client key file

Error message

client cert file %q specified without client key file

What it means

A pairing guard in NewTLSConfig: the configuration specifies a client certificate file (tls_configs.cert_file) without the corresponding key file (key_file). A mTLS client identity needs both halves; the guard fires before any network activity, naming the cert file at fault.

Solutions

  1. Provide both cert_file and key_file, or remove cert_file.
  2. Check flag/config wiring so both files are set together.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at pkg/exthttp/tlsconfig.go:47 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/b2ac5d887546ad20. Report an issue: GitHub.

Appendix: source

Thrown at pkg/exthttp/tlsconfig.go:47

	tlsConfig := &tls.Config{InsecureSkipVerify: cfg.InsecureSkipVerify}

	// If a CA cert is provided then let's read it in.
	if len(cfg.CAFile) > 0 {
		b, err := readCAFile(cfg.CAFile)
		if err != nil {
			return nil, err
		}
		if !updateRootCA(tlsConfig, b) {
			return nil, fmt.Errorf("unable to use specified CA cert %s", cfg.CAFile)
		}
	}

	if len(cfg.ServerName) > 0 {
		tlsConfig.ServerName = cfg.ServerName
	}
	// If a client cert & key is provided then configure TLS config accordingly.
	if len(cfg.CertFile) > 0 && len(cfg.KeyFile) == 0 {
		return nil, fmt.Errorf("client cert file %q specified without client key file", cfg.CertFile)
	} else if len(cfg.KeyFile) > 0 && len(cfg.CertFile) == 0 {
		return nil, fmt.Errorf("client key file %q specified without client cert file", cfg.KeyFile)
	} else if len(cfg.CertFile) > 0 && len(cfg.KeyFile) > 0 {
		// Verify that client cert and key are valid.
		if _, err := cfg.getClientCertificate(nil); err != nil {
			return nil, err
		}
		tlsConfig.GetClientCertificate = cfg.getClientCertificate
	}

	return tlsConfig, nil
}

// readCAFile reads the CA cert file from disk.
func readCAFile(f string) ([]byte, error) {
	data, err := os.ReadFile(f)
	if err != nil {
		return nil, fmt.Errorf("unable to load specified CA cert %s: %s", f, err)

View on GitHub (pinned to 35b8b99117)