crowdsecurity/crowdsec · error
unknown TLS client_verification value: %s
Error message
unknown TLS client_verification value: %s
What it means
TLSCfg.GetAuthType translates the client_verification string into a crypto/tls.ClientAuthType. The switch accepts NoClientCert, RequestClientCert, RequireAnyClientCert, VerifyClientCertIfGiven, and RequireAndVerifyClientCert; any other value hits the default branch and returns this error, which propagates through GetTLSConfig and aborts TLS setup.
Source
Thrown at pkg/csconfig/tls.go:45
// sounds like a sane default: verify client cert if given, but don't make it mandatory
return tls.VerifyClientCertIfGiven, nil
}
switch t.ClientVerification {
case "NoClientCert":
return tls.NoClientCert, nil
case "RequestClientCert":
log.Warn("RequestClientCert is insecure, please use VerifyClientCertIfGiven or RequireAndVerifyClientCert instead")
return tls.RequestClientCert, nil
case "RequireAnyClientCert":
log.Warn("RequireAnyClientCert is insecure, please use VerifyClientCertIfGiven or RequireAndVerifyClientCert instead")
return tls.RequireAnyClientCert, nil
case "VerifyClientCertIfGiven":
return tls.VerifyClientCertIfGiven, nil
case "RequireAndVerifyClientCert":
return tls.RequireAndVerifyClientCert, nil
default:
return 0, fmt.Errorf("unknown TLS client_verification value: %s", t.ClientVerification)
}
}
func (t *TLSCfg) GetTLSConfig() (*tls.Config, error) {
if t == nil {
return &tls.Config{}, nil
}
clientAuthType, err := t.GetAuthType()
if err != nil {
return nil, err
}
caCertPool, err := x509.SystemCertPool()
if err != nil {
log.Warnf("Error loading system CA certificates: %s", err)
}
View on GitHub (pinned to 909b515798)
Solutions
- Set client_verification to exactly one of: NoClientCert, RequestClientCert, RequireAnyClientCert, VerifyClientCertIfGiven, RequireAndVerifyClientCert.
- Match Go's spelling, not nginx's — replace 'required' with RequireAndVerifyClientCert and 'optional' with VerifyClientCertIfGiven.
- Check casing: the comparison is case-sensitive, so write the value in Go constant form (PascalCase).
- If you don't need client certs, simply omit client_verification or set NoClientCert.
Example fix
// before (api.server.tls in config.yaml) tls: client_verification: required // after tls: client_verification: RequireAndVerifyClientCert
Defensive patterns
Strategy: validation
Validate before calling
var valid = []string{"NoClientCert", "RequestClientCert", "RequireAnyClientCert", "VerifyClientCertIfGiven", "RequireAndVerifyClientCert"}
if !slices.Contains(valid, tlsCfg.ClientVerification) {
return fmt.Errorf("client_verification %q must be one of %v", tlsCfg.ClientVerification, valid)
} Try / catch
if _, err := tlsCfg.GetAuthType(); err != nil {
log.Fatalf("bad TLS config: %v", err) // correct client_verification before starting LAPI
} Prevention
- Use Go's exact ClientAuthType names (PascalCase) — not nginx/apache values.
- Copy mTLS config snippets only from crowdsec docs, not other servers.
- Validate the tls section with a schema check in deployment tooling.
When it happens
Trigger: The tls section of the API server config sets client_verification to a value outside the five supported enum strings — typos like 'require_and_verify', 'required', or mixed case ('RequireAndVerifyclientcert' — matching is case-sensitive).
Common situations: Operators copy mTLS snippets from nginx ('optional', 'required') or other servers whose enum names differ; editing api.server.tls.client_verification by hand with a wrong casing.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- allowed_ou configuration contains invalid empty string
- machine %s attempted to auth with TLS cert but it is configu
- failed to load api client certificate: %w
- path must start with /
- basic_auth is selected, but basic_auth is not provided
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/8f24135b9f99ee96.
Report an issue: GitHub.