thanos-io/thanos · error

both server key and certificate must be provided

Error message

both server key and certificate must be provided

What it means

NewServerConfig throws this when exactly one of the server key or certificate path is provided. TLS requires both a certificate and its matching private key; providing only one is an incomplete server TLS configuration.

Solutions

  1. Provide both --cert and --key pointing to a matching PEM keypair
  2. Check secret/volume mounts so both files exist at the given paths
  3. Verify the cert and key pair match (compare modulus/public keys with openssl)
  4. Fix templating so cert and key paths are always set together

Example fix

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

Strategy: validation

Validate before calling

// Pre-start check
if (certPath == "") != (keyPath == "") {
    return errors.New("--cert and --key must be provided together")
}

Prevention

When it happens

Trigger: A run* command is started with only --cert or only --key set (the other empty), after passing the both-empty early-return check.

Common situations: One of two secret-mounted file paths misconfigured in Kubernetes; typo in one flag; secret volume mounted but one path templated wrong; half-updated config after cert rotation.

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/8f1362530a195c69. Report an issue: GitHub.

Appendix: source

Thrown at pkg/tls/options.go:39

// 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{
		MinVersion: minTlsVersion,
	}

	cipherSuiteIDs, err := getCipherSuiteIDs(ciphers)
	if err != nil {
		return nil, err
	}
	tlsCfg.CipherSuites = cipherSuiteIDs

	curveIDs, err := getCurveIDs(curves)

View on GitHub (pinned to 35b8b99117)