crowdsecurity/crowdsec · error
machine '%s': %w
Error message
machine '%s': %w
What it means
CreateAlert wraps any error returned by QueryMachineByID when looking up the alert's owning machine. The wrapper preserves the underlying cause (%w) while stating which machine the lookup failed for. Note it is deliberately NOT raised when the error is the sentinel UserNotExists — that case just means the machine has no owner record and the alert is created ownerless.
Source
Thrown at pkg/database/alerts.go:734
if err := tx.Commit(); err != nil {
return nil, fmt.Errorf("committing alert transaction: %w: %w", err, BulkError)
}
return ids, nil
}
func (c *Client) CreateAlert(ctx context.Context, machineID string, alertList []*models.Alert) ([]string, error) {
var (
owner *ent.Machine
err error
)
if machineID != "" {
owner, err = c.QueryMachineByID(ctx, machineID)
if err != nil {
if !errors.Is(err, UserNotExists) {
return nil, fmt.Errorf("machine '%s': %w", machineID, err)
}
c.Log.Debugf("creating alert: machine %s doesn't exist", machineID)
owner = nil
}
}
c.Log.Debugf("writing %d items", len(alertList))
alertIDs := []string{}
if err := slicetools.Batch(ctx, alertList, alertCreateBulkSize, func(ctx context.Context, part []*models.Alert) error {
ids, err := c.createAlertBatch(ctx, machineID, owner, part)
if err != nil {
return fmt.Errorf("machine %q: %w", machineID, err)
}
alertIDs = append(alertIDs, ids...)
return nilView on GitHub (pinned to 909b515798)
Solutions
- Check the wrapped cause with errors.Is/errors.As to see the real DB error
- Verify database connectivity and credentials in crowdsec.yaml (db_config)
- Retry the push; transient DB failures often resolve once the pool recovers
- If the machine should exist, confirm it with `cscli machines list` and re-register if needed
Example fix
// before
if !errors.Is(err, UserNotExists) {
return nil, fmt.Errorf("machine '%s': %w", machineID, err)
}
// after (only if treating missing machine as fatal is wrong for your flow)
if !errors.Is(err, UserNotExists) {
if errors.Is(err, context.DeadlineExceeded) {
return nil, fmt.Errorf("machine '%s': lookup timed out, retry push: %w", machineID, err)
}
return nil, fmt.Errorf("machine '%s': %w", machineID, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if machineID == "" {
return errors.New("machineID required to attribute alert")
} Try / catch
alertIDs, err := client.CreateAlert(ctx, alert)
if err != nil {
if strings.HasPrefix(err.Error(), "machine '") {
// inspect wrapped cause via errors.Is/As
}
return fmt.Errorf("create alert: %w", err)
} Prevention
- Ensure the machine is registered (cscli machines add) before pushing alerts
- Keep DB credentials and connectivity validated at startup
- Pass a context with adequate timeout for alert pushes
When it happens
Trigger: CreateAlert/CreateOrUpdateAlert called with a machineID whose QueryMachineByID fails with an error other than UserNotExists (DB connectivity failure, ent query error, context cancellation).
Common situations: Database down or migrated mid-push; alerts pushed by a machine during a context timeout; MySQL/SQLite connection pool exhausted on busy LAPI instances.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- event meta '%v': %w: %w
- no database configuration provided
- unable to update
- unable to delete
- object not found
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/1a7bed0837fbd0eb.
Report an issue: GitHub.