crowdsecurity/crowdsec · error
unable to query alerts for uuid %s: %w
Error message
unable to query alerts for uuid %s: %w
What it means
CreateOrUpdateAlert queries the alerts table for an alert by UUID; if the ent query itself fails with an error other than not-found, the alert cannot be checked and this wrapped error is returned. It means the lookup SELECT against the alert repository failed, not that the alert is missing (missing alerts are handled by inserting a new one).
Source
Thrown at pkg/database/alerts.go:52
func rollbackOnError(tx *ent.Tx, err error, msg string) error {
if rbErr := tx.Rollback(); rbErr != nil {
log.Errorf("rollback error: %v", rbErr)
}
return fmt.Errorf("%s: %w", msg, err)
}
// CreateOrUpdateAlert is specific to PAPI : It checks if alert already exists, otherwise inserts it
// if alert already exists, it checks it associated decisions already exists
// if some associated decisions are missing (ie. previous insert ended up in error) it inserts them
func (c *Client) CreateOrUpdateAlert(ctx context.Context, machineID string, alertItem *models.Alert) (string, error) {
if alertItem.UUID == "" {
return "", errors.New("alert UUID is empty")
}
alerts, err := c.Ent.Alert.Query().Where(alert.UUID(alertItem.UUID)).WithDecisions().All(ctx)
if err != nil && !ent.IsNotFound(err) {
return "", fmt.Errorf("unable to query alerts for uuid %s: %w", alertItem.UUID, err)
}
// alert wasn't found, insert it (expected hotpath)
if ent.IsNotFound(err) || len(alerts) == 0 {
alertIDs, err := c.CreateAlert(ctx, machineID, []*models.Alert{alertItem})
if err != nil {
return "", fmt.Errorf("unable to create alert: %w", err)
}
// happy nilaway
if len(alertIDs) == 0 {
return "", fmt.Errorf("unable to create alert: no IDs returned for alert %s", alertItem.UUID)
}
return alertIDs[0], nil
}
// this should never happenView on GitHub (pinned to 909b515798)
Solutions
- Check DB connectivity and credentials in crowdsec's db_config
- Run 'cscli db migrate' / confirm the DB schema matches the installed crowdsec version
- For SQLite locks, look for other processes holding the DB and consider moving to PostgreSQL/MySQL
- Retry the operation once connectivity/locks are resolved; the operation is idempotent by alert UUID
Example fix
// before: treating any error as fatal without checking DB
// after: surface the cause and verify DB health first
if _, err := client.CreateOrUpdateAlert(ctx, machineID, alert); err != nil {
if err := dbHealthCheck(ctx); err != nil {
return fmt.Errorf("db unhealthy: %w", err)
}
return err
} Defensive patterns
Strategy: retry
Validate before calling
// verify DB reachable before pushing alerts
if err := c.Ent.Schema.Create(ctx) /* or a trivial query */; err != nil { return err }
if alertItem.UUID == "" { return errors.New("pre-check: alert UUID is empty") } Try / catch
id, err := client.CreateOrUpdateAlert(ctx, machineID, alert)
if err != nil && strings.HasPrefix(err.Error(), "unable to query alerts") {
// DB-level failure, not 'not found': retry after health check
if isDbHealthy(ctx) { id, err = client.CreateOrUpdateAlert(ctx, machineID, alert) }
} Prevention
- Health-check the DB connection before bulk PAPI pushes
- Use context timeouts generous enough for SQLite under load
- Match crowdsec binary and DB schema versions on upgrade
- Serialize alert pushes rather than issuing them concurrently from many clients
When it happens
Trigger: c.Ent.Alert.Query().Where(alert.UUID(...)).WithDecisions().All(ctx) returns a non-NotFound error: DB connection failure, SQLite lock/timeout, corrupted schema, or context cancellation during the PAPI AlertCmd flow.
Common situations: SQLite file locked by another crowdsec process; database migrated to a schema the binary doesn't understand after upgrade; DB unreachable (remote PostgreSQL/MySQL down); context deadline exceeded on a slow disk.
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
- expired decisions: %w
- while getting alert: %w
- while getting decision: %w
- select config item: %w: %w
- count all decisions with filters: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/2fa0ae023250a896.
Report an issue: GitHub.