crowdsecurity/crowdsec · error

machine %s not validated

Error message

machine %s not validated

What it means

This error is returned by the crowdsec LAPI's password ('plain') authentication path when a machine (agent or bouncer) that registered with the API attempts to log in with username/password, but its account has not been validated yet. New auto-registered machines must be approved (manually or automatically) before they can authenticate; IsValidated is the approval flag in the machine's DB record. Until it is set, every login attempt is rejected even if the password is correct.

Source

Thrown at pkg/apiserver/middlewares/v1/jwt.go:165

	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
	}

	if ret.clientMachine == nil {
		log.Errorf("Nothing for '%s'", ret.machineID)
		return nil, jwt.ErrFailedAuthentication
	}

	if ret.clientMachine.AuthType != types.PasswordAuthType {
		return nil, fmt.Errorf("machine %s attempted to auth with password but it is configured to use %s", ret.machineID, ret.clientMachine.AuthType)
	}

	if !ret.clientMachine.IsValidated {
		return nil, fmt.Errorf("machine %s not validated", ret.machineID)
	}

	if err := bcrypt.CompareHashAndPassword([]byte(ret.clientMachine.Password), []byte(password)); err != nil {
		return nil, jwt.ErrFailedAuthentication
	}

	return &ret, nil
}

func (j *JWT) Authenticator(c *gin.Context) (any, error) {
	var (
		err  error
		auth *authInput
	)

	ctx := c.Request.Context()

	if c.Request.TLS != nil && len(c.Request.TLS.PeerCertificates) > 0 {

View on GitHub (pinned to 909b515798)

Solutions

  1. Validate the machine: `cscli machines validate <machine-name>` (run on the LAPI server).
  2. Check `cscli machines list` — the 'validated' column must be true before the client can log in.
  3. If many machines should be trusted automatically, enable auto-registration validation (register with a token or set auto_register with validation in the api.server config).
  4. If the machine is unknown/unwanted, delete it with `cscli machines delete <name>` and re-register it properly.

Example fix

// before: machine shows in cscli machines list as not validated, agent logs keep failing
$ cscli machines list
NAME      VALIDATED
agent01   ✗
// after
$ cscli machines validate agent01
$ cscli machines list
NAME      VALIDATED
agent01   ✓
Defensive patterns

Strategy: validation

Validate before calling

out, err := exec.Command("cscli", "machines", "list", "-o", "json").Output()
// parse and check the machine's 'isValidated' field is true before configuring the agent/bouncer credentials

Try / catch

if err != nil {
    if strings.Contains(err.Error(), "not validated") {
        // surface instruction to run: cscli machines validate <machine>
    }
}

Prevention

When it happens

Trigger: A machine registered with `cscli machines add` lacking -a/auto validation, or self-registered via the /register endpoint while api.server.auto_register was disabled or required manual approval, and the operator never ran `cscli machines validate`. The machine then retries JWT login (cscli capi/lapi login) and gets this rejection before the bcrypt password comparison.

Common situations: Fresh agent/bouncer enrollments where the admin generated credentials but forgot the validation step; setups with require_manual_validation enabled and no approval workflow; re-creating a machine record in the DB without setting is_validated.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/ac1731d104bf75ec. Report an issue: GitHub.