thanos-io/thanos · error

when a client CA is used a server key and certificate must…

Error message

when a client CA is used a server key and certificate must also be provided

What it means

NewServerConfig in pkg/tls rejects the combination of a client CA being provided without any server key/certificate. Serving TLS with client certificate authentication (mTLS) requires the server itself to present a keypair; enabling only the CA is an invalid configuration.

Solutions

  1. Provide --cert and --key alongside --client-ca to enable full mTLS
  2. If TLS is not wanted, remove the --client-ca flag instead
  3. Validate TLS flags in deployment tooling before rollout
  4. Check generated configs/templates include all three TLS paths

Example fix

// before
--client-ca=ca.crt
// after
--client-ca=ca.crt --cert=server.crt --key=server.key
Defensive patterns

Strategy: validation

Validate before calling

// Startup validation wrapper
if clientCA != "" && (certPath == "" || keyPath == "") {
    return errors.New("mTLS requires --client-ca, --cert and --key all set")
}

Prevention

When it happens

Trigger: A run* command (runQuery, runReceive, runRule, runSidecar, runStore) is started with --client-ca set but --cert and --key both empty.

Common situations: Operators setting only --client-ca intending to enable mTLS but forgetting the server cert/key flags; partially templated Helm/manifest configs where cert paths were dropped.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at pkg/tls/options.go:29

	"path/filepath"
	"sort"
	"strings"
	"sync"
	"time"

	"github.com/go-kit/log"
	"github.com/go-kit/log/level"
	"github.com/pkg/errors"
)

// AllowedTLSVersions is for global lists the TLS versions allowed to be used.
var AllowedTLSVersions = []string{"1.0", "1.1", "1.2", "1.3"}

// NewServerConfig provides new server TLS configuration.
func NewServerConfig(logger log.Logger, certPath, keyPath, clientCA, tlsMinVersion string, ciphers []string, curves []string) (*tls.Config, error) {
	if keyPath == "" && certPath == "" {
		if clientCA != "" {
			return nil, errors.New("when a client CA is used a server key and certificate must also be provided")
		}

		level.Info(logger).Log("msg", "disabled TLS, key and cert must be set to enable")
		return nil, nil
	}

	level.Info(logger).Log("msg", "enabling server side TLS")

	if keyPath == "" || certPath == "" {
		return nil, errors.New("both server key and certificate must be provided")
	}

	minTlsVersion, err := GetTlsVersion(tlsMinVersion)
	if err != nil {
		return nil, err
	}

	tlsCfg := &tls.Config{

View on GitHub (pinned to 35b8b99117)