crowdsecurity/crowdsec · error
missing scenarios list in login request for TLS auth: %w
Error message
missing scenarios list in login request for TLS auth: %w
What it means
In TLS auth the login request body must contain a 'scenarios' list (used for license/usage tracking even though certs do the real auth). ShouldBindJSON failed — body empty, malformed JSON, or wrong content-type — so authTLS wraps it as 'missing scenarios list in login request for TLS auth'.
Source
Thrown at pkg/apiserver/middlewares/v1/jwt.go:117
} else if err != nil {
return nil, fmt.Errorf("while selecting machine entry for %s: %w", ret.machineID, err)
} else {
if ret.clientMachine.AuthType != types.TlsAuthType {
return nil, fmt.Errorf("machine %s attempted to auth with TLS cert but it is configured to use %s", ret.machineID, ret.clientMachine.AuthType)
}
ret.machineID = ret.clientMachine.MachineId
}
loginInput := struct {
Scenarios []string `json:"scenarios"`
}{
Scenarios: []string{},
}
err = c.ShouldBindJSON(&loginInput)
if err != nil {
return nil, fmt.Errorf("missing scenarios list in login request for TLS auth: %w", err)
}
ret.scenariosInput = loginInput.Scenarios
return &ret, nil
}
func (j *JWT) authPlain(c *gin.Context) (*authInput, error) {
var (
loginInput models.WatcherAuthRequest
err error
)
ctx := c.Request.Context()
ret := authInput{}
if err = c.ShouldBindJSON(&loginInput); err != nil {View on GitHub (pinned to 909b515798)
Solutions
- Send a valid JSON body, e.g. {"scenarios":[]}, with Content-Type: application/json when logging in via TLS
- Upgrade the crowdsec agent/bouncer to a version that sends scenarios on TLS login
- Test with: curl --cert ... --key ... -H 'Content-Type: application/json' -d '{"scenarios":[]}' https://lapi:8080/api/v1/watchers/login','If you control a custom client, always include the scenarios key (empty list is acceptable)
Example fix
// before
curl -sk --cert client.pem --key client.key -X POST https://lapi:8080/api/v1/watchers/login
// after
curl -sk --cert client.pem --key client.key -H 'Content-Type: application/json' -d '{"scenarios":[]}' -X POST https://lapi:8080/api/v1/watchers/login Defensive patterns
Strategy: validation
Validate before calling
// validate the TLS login payload before sending
body := map[string][]string{"scenarios": {}}
data, _ := json.Marshal(body)
if !json.Valid(data) {
return errors.New("invalid TLS login body")
}
req.Header.Set("Content-Type", "application/json") Try / catch
resp, err := http.Do(tlsLoginReq)
if err != nil || (resp != nil && resp.StatusCode == http.StatusBadRequest) {
return fmt.Errorf("TLS login rejected, ensure body is {\"scenarios\":[]} with JSON content-type: %w", err)
} Prevention
- Always send {"scenarios":[]} (or a real list) with Content-Type: application/json on TLS login
- Use supported crowdsec client versions that include scenarios in TLS login
- When scripting, never use bare -X POST without a JSON body
- Test custom integrations against a local LAPI before production
When it happens
Trigger: Authenticator -> authTLS: a mTLS client POSTs /api/v1/watchers/login without a JSON body, with invalid JSON, or without Content-Type: application/json; c.ShouldBindJSON returns a binding error which is wrapped.
Common situations: Hand-rolled scripts curling the login endpoint with no body; old/patched agent versions that omit the scenarios field; proxy stripping request bodies; testing with 'curl -X POST' and no -d.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- missing: %w
- while creating machine entry for %s: %w
- while selecting machine entry for %s: %w
- authorization header not found
- multiple Authorization headers found
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/1bb719f04cba9106.
Report an issue: GitHub.