crowdsecurity/crowdsec · error
missing: %w
Error message
missing: %w
What it means
authPlain requires a JSON login body (machine_id + password). ShouldBindJSON failed — missing, empty, or malformed body — and the error is tersely wrapped as 'missing: %w'. It is the password-auth counterpart of the TLS scenarios binding error.
Source
Thrown at pkg/apiserver/middlewares/v1/jwt.go:136
}
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 {
return nil, fmt.Errorf("missing: %w", err)
}
if err = loginInput.Validate(strfmt.Default); err != nil {
return nil, err
}
ret.machineID = *loginInput.MachineID
password := *loginInput.Password
ret.scenariosInput = loginInput.Scenarios
ret.clientMachine, err = j.DbClient.Ent.Machine.Query().
Where(machine.MachineId(ret.machineID)).
First(ctx)
if err != nil {
log.Infof("Error machine login for %s : %+v ", ret.machineID, err)
return nil, err
}
View on GitHub (pinned to 909b515798)
Solutions
- POST valid JSON with Content-Type: application/json: {"machine_id":"...","password":"..."}
- Check the agent's local credentials file (/etc/crowdsec/local_api_credentials.yaml) is populated and the agent uses it
- Test manually: curl -H 'Content-Type: application/json' -d '{"machine_id":"x","password":"y"}' https://lapi:8080/api/v1/watchers/login','Inspect any proxy/LB config that could drop or rewrite the request body
Example fix
// before
curl -X POST https://lapi:8080/api/v1/watchers/login
// after
curl -H 'Content-Type: application/json' -d '{"machine_id":"myagent","password":"secret"}' -X POST https://lapi:8080/api/v1/watchers/login Defensive patterns
Strategy: validation
Validate before calling
// build and validate the login payload before the request
login := struct {
MachineID string `json:"machine_id"`
Password string `json:"password"`
}{machineID, password}
if login.MachineID == "" || login.Password == "" {
return errors.New("machine_id and password are required")
}
body, _ := json.Marshal(login) Try / catch
resp, err := http.Post(lapiURL+"/api/v1/watchers/login", "application/json", bytes.NewReader(body))
if err != nil {
return fmt.Errorf("password login failed, check JSON body and content-type: %w", err)
} Prevention
- Always send Content-Type: application/json with machine_id and password fields
- Verify local_api_credentials.yaml is populated before starting password-auth watchers
- Check proxies/LBs do not strip or rewrite POST bodies
- Guard credential loading: fail fast if machine_id/password resolve to empty strings
When it happens
Trigger: Authenticator -> authPlain: POST /api/v1/watchers/login with no body, invalid JSON, wrong Content-Type, or missing machine_id/password fields so gin's JSON binding fails and returns 'missing: <binding error>'.
Common situations: Scripts using wrong Content-Type (form instead of JSON); empty curl -d ''; credentials file not loaded by the agent (empty machine_id/password); load balancer or proxy stripping the body on POST.
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.
Related errors
- missing scenarios list in login request for TLS auth: %w
- authorization header not found
- multiple Authorization headers found
- authorization header does not start with 'Basic '
- authorization header does not start with 'Bearer '
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/f506fc3c83a4f904.
Report an issue: GitHub.