crowdsecurity/crowdsec · error

fail to count decisions: %w

Error message

fail to count decisions: %w

What it means

CountDecisionsByValue failed while executing the ent ORM COUNT query against the decisions table. The error wraps the underlying database/driver error after building the query (optionally filtered to active decisions via `until > now`). It indicates the count could not be retrieved from the database backend (SQLite, MySQL, PostgreSQL, etc.).

Source

Thrown at pkg/database/decisions.go:406

	contains := true
	decisions := c.Ent.Decision.Query()

	decisions, err = decisionIPFilter(decisions, contains, rng)
	if err != nil {
		return 0, fmt.Errorf("fail to apply StartIpEndIpFilter: %w", err)
	}

	if since != nil {
		decisions = decisions.Where(decision.CreatedAtGT(*since))
	}

	if onlyActive {
		decisions = decisions.Where(decision.UntilGT(time.Now().UTC()))
	}

	count, err := decisions.Count(ctx)
	if err != nil {
		return 0, fmt.Errorf("fail to count decisions: %w", err)
	}

	return count, nil
}

func (c *Client) GetActiveDecisionsTimeLeftByValue(ctx context.Context, decisionValue string) (time.Duration, error) {
	rng, err := csnet.NewRange(decisionValue)
	if err != nil {
		return 0, fmt.Errorf("unable to convert '%s' to int: %w", decisionValue, err)
	}

	contains := true
	decisions := c.Ent.Decision.Query().Where(
		decision.UntilGT(time.Now().UTC()),
	)

	decisions, err = decisionIPFilter(decisions, contains, rng)
	if err != nil {

View on GitHub (pinned to 909b515798)

Solutions

  1. Verify the database is reachable and credentials in crowdsec.db / /etc/crowdsec/config.yaml are correct.
  2. Check disk space and file permissions if using SQLite.
  3. Run `cscli hubtool` / check crowdsec logs for the wrapped driver error to identify the root cause.
  4. Apply pending migrations: `cscli migrations` / restart crowdsec to run schema migrations.

Example fix

// before: assuming DB is always up
expiredAlerts, err := client.CountDecisionsByValue(ctx, "1.2.3.4", "", "", false)
// after: handle DB failure gracefully
expiredAlerts, err := client.CountDecisionsByValue(ctx, "1.2.3.4", "", "", false)
if err != nil {
	log.Errorf("counting decisions: %v", err)
	// fall back to fail-open or retry later
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: check DB connectivity before counting
if err := client.Healthcheck(ctx); err != nil {
	return fmt.Errorf("database unavailable: %w", err)
}

Try / catch

count, err := client.CountDecisionsByValue(ctx, value, scope, kind, active)
if err != nil {
	log.Warnf("decision count failed (DB issue): %v", err)
	// degrade gracefully: treat as 0 or retry with backoff
}

Prevention

When it happens

Trigger: Calling CountDecisionsByValue with a decision value/type scope when the underlying ent Count(ctx) query fails: DB unreachable, table/schema missing or corrupted, driver error, or query timeout.

Common situations: CrowdSec's DB is down or restarting; SQLite file corrupted or on a read-only/full disk; MySQL/Postgres credentials or network changed after startup; schema migration not applied after 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/2ee6ebb6fc5c8230. Report an issue: GitHub.