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
- Provide both --cert and --key pointing to a matching PEM keypair
- Check secret/volume mounts so both files exist at the given paths
- Verify the cert and key pair match (compare modulus/public keys with openssl)
- 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
- Set cert and key flags from the same config object/secret
- Verify both files exist in the container before launch
- Avoid hand-editing one path of the pair during rotation
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.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- when a client CA is used a server key and certificate must…
- server credentials
- building gRPC client
- setup gRPC server
- setup gRPC server
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)