crowdsecurity/crowdsec · error

unable to count nb alerts

Error message

unable to count nb alerts: %w

What it means

When limit is 0 (unpaginated mode) QueryAlertWithFilter counts matching alerts first; this error wraps a failure of that Count query. The filter was valid but the database could not perform the count.

Solutions

  1. Check the wrapped DB error and database server logs
  2. Retry once connections recover
  3. Use an explicit limit instead of 0 to avoid a full-table count
  4. Consider pruning old alerts (cscli alerts delete --until) to shrink the table
Defensive patterns

Strategy: retry

Try / catch

alerts, err := client.FindAlerts(ctx, filter)
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        // fall back to a paged query with explicit limit
    }
    return err
}

Prevention

When it happens

Trigger: alerts.Count(ctx) fails — DB unreachable, query timeout on a huge alerts table, or context cancelled.

Common situations: Millions of alerts making COUNT(*) slow; SQLite lock contention; DB restarting during a FlushAlerts run.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


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

Appendix: source

Thrown at pkg/database/alerts.go:847

		}

		// only if with_decisions is present and set to false, we exclude this
		if val, ok := filter["with_decisions"]; ok && val[0] == "false" {
			c.Log.Debugf("skipping decisions")
		} else {
			alerts = alerts.
				WithDecisions()
		}

		alerts = alerts.
			WithEvents().
			WithMetas().
			WithOwner()

		if limit == 0 {
			limit, err = alerts.Count(ctx)
			if err != nil {
				return nil, fmt.Errorf("unable to count nb alerts: %w", err)
			}
		}

		if sort == "ASC" {
			alerts = alerts.Order(ent.Asc(alert.FieldCreatedAt), ent.Asc(alert.FieldID))
		} else {
			alerts = alerts.Order(ent.Desc(alert.FieldCreatedAt), ent.Desc(alert.FieldID))
		}

		result, err := alerts.Limit(paginationSize).Offset(offset).All(ctx)
		if err != nil {
			return nil, fmt.Errorf("pagination size: %d, offset: %d: %w: %w", paginationSize, offset, err, QueryFail)
		}

		if len(result) == 0 { // no results, no need to try to paginate further
			c.Log.Debugf("Pagination done because no results found at offset %d | len(ret) %d", offset, len(ret))
			break
		}

View on GitHub (pinned to 909b515798)