crowdsecurity/crowdsec · error

unable to get alerts count: %w

Error message

unable to get alerts count: %w

What it means

FlushAlerts needs the total alert count to enforce the max_items limit. When c.TotalAlerts fails (a database query error), the function logs a warning and returns this wrapped error instead of proceeding with the flush.

Source

Thrown at pkg/database/flush.go:328

		deletedByNbItem int
		totalAlerts     int
		err             error
	)

	if !c.TryFlushLock() {
		c.Log.Debug("a list is being imported, flushing later")
		return nil
	}
	defer c.FlushUnlock()

	c.Log.Debug("Flushing orphan alerts")
	c.FlushOrphans(ctx)
	c.Log.Debug("Done flushing orphan alerts")

	totalAlerts, err = c.TotalAlerts(ctx)
	if err != nil {
		c.Log.Warningf("FlushAlerts (max items count): %s", err)
		return fmt.Errorf("unable to get alerts count: %w", err)
	}

	c.Log.Debugf("FlushAlerts (Total alerts): %d", totalAlerts)

	if maxAge != 0 {
		now := time.Now().UTC()

		// Delete alerts older than maxAge, but never one that still has an
		// active decision (the cascade would take the live decision with it).
		nbDeleted, err := c.Ent.Alert.Delete().Where(
			alert.CreatedAtLTE(now.Add(-maxAge)),
			alertWithoutActiveDecision(now),
		).Exec(ctx)
		if err != nil {
			c.Log.Warningf("FlushAlerts (max age): %s", err)
			return fmt.Errorf("unable to flush alerts older than %s: %w", maxAge, err)
		}

View on GitHub (pinned to 909b515798)

Solutions

  1. Check database connectivity and that the DB process is running (e.g. systemctl status postgresql / mysql).
  2. If using SQLite, ensure no other process holds the DB file lock and the file path is writable.
  3. Run cscli database migrate (or restart crowdsec) to ensure the schema is up to date after a version upgrade.
  4. Inspect the wrapped error (%w) for the driver-specific message (e.g. 'connection refused', 'no such table') and address that.
  5. For repeated failures, verify db_config credentials and network reachability in crowdsec's config.yaml.

Example fix

// check DB is reachable before/when debugging
// before: silently failing remote DB
db_config:
  type: postgresql
  host: 10.0.0.5
// after: fix host/port and credentials, then verify
db_config:
  type: postgresql
  host: 10.0.0.5
  port: 5432
  user: crowdsec
  password: correct-password
  db_name: crowdsec
Defensive patterns

Strategy: try-catch

Validate before calling

// probe connectivity before running flushes
if err := c.Ent.Alert.Query().Limit(1).Exec(ctx); err != nil {
    return fmt.Errorf("database unreachable: %w", err)
}

Type guard

if c == nil || c.Ent == nil {
    return errors.New("database client not initialized")
}

Try / catch

if err := c.FlushAlerts(ctx, maxAge, maxItems); err != nil {
    if strings.Contains(err.Error(), "unable to get alerts count") {
        // database query failed; check connectivity and retry later
    }
    return err
}

Prevention

When it happens

Trigger: The underlying ent query for the alerts count fails: database unreachable, connection dropped mid-query, schema/table 'alerts' missing, or a context timeout/cancel during the count query.

Common situations: SQLite file locked by another process (concurrent cscli commands), Postgres/MySQL restarted, network interruption to a remote DB, or the database schema not migrated after an upgrade.

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


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