crowdsecurity/crowdsec · error

unable to update machine version in database: %w

Error message

unable to update machine version in database: %w

What it means

UpdateMachineVersion returns the raw ent error when Machine.UpdateOneID(id).SetVersion(ipAddr).Save(ctx) fails while storing the watcher's crowdsec version. It is invoked from Authenticator during watcher authentication. Same failure modes as the other UpdateOneID callers: missing row (concurrent delete) or DB-level failure. (Note the parameter is misleadingly named ipAddr but carries the version string.)

Source

Thrown at pkg/database/machines.go:229

}

func (c *Client) UpdateMachineIP(ctx context.Context, ipAddr string, id int) error {
	_, err := c.Ent.Machine.UpdateOneID(id).
		SetIpAddress(ipAddr).
		Save(ctx)
	if err != nil {
		return fmt.Errorf("unable to update machine IP in database: %w", err)
	}

	return nil
}

func (c *Client) UpdateMachineVersion(ctx context.Context, ipAddr string, id int) error {
	_, err := c.Ent.Machine.UpdateOneID(id).
		SetVersion(ipAddr).
		Save(ctx)
	if err != nil {
		return fmt.Errorf("unable to update machine version in database: %w", err)
	}

	return nil
}

func (c *Client) QueryMachinesInactiveSince(ctx context.Context, t time.Time) ([]*ent.Machine, error) {
	return c.Ent.Machine.Query().Where(
		machine.Or(
			machine.And(machine.LastHeartbeatLT(t), machine.IsValidatedEQ(true)),
			machine.And(machine.LastHeartbeatIsNil(), machine.CreatedAtLT(t)),
		),
	).All(ctx)
}

View on GitHub (pinned to 909b515798)

Solutions

  1. Inspect the wrapped error; handle ent not-found separately from infra failures
  2. Verify the machine still exists and retry once with fresh row data
  3. Check DB health (connectivity, locks, disk) if this recurs across watchers
  4. Keep the machines table consistent: avoid deleting rows while auths are in flight, or accept the benign not-found
Defensive patterns

Strategy: try-catch

Validate before calling

m, err := db.QueryMachineByID(ctx, machineID)
if err != nil { return err }
err = db.UpdateMachineVersion(ctx, version, m.ID)

Try / catch

if err := db.UpdateMachineVersion(ctx, version, id); err != nil {
    if _, qerr := db.QueryMachineByID(ctx, machineID); errors.Is(qerr, database.UserNotExists) {
        return nil // machine vanished concurrently
    }
    return err
}

Prevention

When it happens

Trigger: Authenticator detects a version change and persists it; the update fails because the machine row is gone (prune/delete race) or the DB write fails (lock, down, disk full).

Common situations: Watcher upgrading its crowdsec version while its machine entry is being pruned; SQLite contention at scale; DB restart during the auth request.

Related errors


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