crowdsecurity/crowdsec · error
unable to update machine in database: %w
Error message
unable to update machine in database: %w
What it means
UpdateMachineScenarios returns the raw ent error (no sentinel) when Machine.UpdateOneID(id) fails while persisting the machine's scenario list. This is called during Authenticator, i.e. when a validated watcher authenticates; a stale/unknown row id makes ent return a not-found error here. Note the message text is slightly off — it's a generic update failure, not 'machine' specific.
Source
Thrown at pkg/database/machines.go:207
return nbDeleted, nil
}
func (c *Client) UpdateMachineLastHeartBeat(ctx context.Context, machineID string) error {
_, err := c.Ent.Machine.Update().Where(machine.MachineIdEQ(machineID)).SetLastHeartbeat(time.Now().UTC()).Save(ctx)
if err != nil {
return fmt.Errorf("updating machine last_heartbeat: %w: %w", err, UpdateFail)
}
return nil
}
func (c *Client) UpdateMachineScenarios(ctx context.Context, scenarios string, id int) error {
_, err := c.Ent.Machine.UpdateOneID(id).
SetUpdatedAt(time.Now().UTC()).
SetScenarios(scenarios).
Save(ctx)
if err != nil {
return fmt.Errorf("unable to update machine in database: %w", err)
}
return nil
}
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).View on GitHub (pinned to 909b515798)
Solutions
- Re-check the machine still exists (QueryMachineByID) before/after the update and handle deletion races gracefully
- Inspect the wrapped error: ent not-found vs connection failure lead to different fixes
- If races with prune/delete are common, re-fetch the machine row and retry once
- Ensure DB is writable and the schema matches (`cscli migration`)
Example fix
// before
if err := db.UpdateMachineScenarios(ctx, scenarios, machine.ID); err != nil {
return err
}
// after
if err := db.UpdateMachineScenarios(ctx, scenarios, machine.ID); err != nil {
if _, qerr := db.QueryMachineByID(ctx, machine.MachineId); errors.Is(qerr, database.UserNotExists) {
return nil // machine deleted concurrently; nothing to update
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// refresh the row before the id-based update
m, err := db.QueryMachineByID(ctx, machineID)
if err != nil { return err }
err = db.UpdateMachineScenarios(ctx, scenarios, m.ID) Try / catch
if err := db.UpdateMachineScenarios(ctx, scenarios, id); err != nil {
if _, qerr := db.QueryMachineByID(ctx, machineID); errors.Is(qerr, database.UserNotExists) {
return nil // benign: machine deleted concurrently
}
return err
} Prevention
- Re-fetch machine rows before id-based updates in auth hot paths
- Avoid pruning/deleting machines while auth requests are in flight (or handle the race)
- Treat ent not-found on these updates as benign and log at debug level
- Check HandleDBErrors (pkg/apiserver/controllers/v1/errors.go) to map these to correct HTTP codes
When it happens
Trigger: Authenticator detects the machine's scenario list changed and calls UpdateMachineScenarios, but the row with the given auto-increment id was deleted concurrently, or the DB write fails (lock, connection).
Common situations: Machine deleted (prune/`cscli machines delete`) while its heartbeat/auth was in flight; DB busy on SQLite; id passed from a stale cached row.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- unable to update machine IP in database: %w
- unable to update machine version in database: %w
- validating machine: %w: %w
- updating machine last_heartbeat: %w: %w
- no database configuration provided
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/5846e30b30f63420.
Report an issue: GitHub.