crowdsecurity/crowdsec · error
unable to expire decisions %+v: %w
Error message
unable to expire decisions %+v: %w
What it means
After parsing UUIDs from a delete-decisions PAPI message, DecisionCmd expires the matching decisions in the local database via ExpireDecisionsWithFilter. This error means the database expiry operation failed, so remote deletion orders could not be applied locally.
Source
Thrown at pkg/apiserver/papi_cmd.go:63
UUIDs := make([]string, 0)
deleteDecisionMsg := deleteDecisions{
Decisions: make([]string, 0),
}
if err := json.Unmarshal(data, &deleteDecisionMsg); err != nil {
return fmt.Errorf("message for '%s' contains bad data format: %w", message.Header.OperationType, err)
}
UUIDs = append(UUIDs, deleteDecisionMsg.Decisions...)
log.Infof("Decisions UUIDs to remove: %+v", UUIDs)
filter := make(map[string][]string)
filter["uuid"] = UUIDs
_, deletedDecisions, err := p.DBClient.ExpireDecisionsWithFilter(ctx, filter)
if err != nil {
return fmt.Errorf("unable to expire decisions %+v: %w", UUIDs, err)
}
decisions := make([]*models.Decision, 0)
for _, deletedDecision := range deletedDecisions {
log.Infof("Decision from '%s' for '%s' (%s) has been deleted", deletedDecision.Origin, deletedDecision.Value, deletedDecision.Type)
dec := &models.Decision{
UUID: deletedDecision.UUID,
Origin: &deletedDecision.Origin,
Scenario: &deletedDecision.Scenario,
Scope: &deletedDecision.Scope,
Value: &deletedDecision.Value,
ID: int64(deletedDecision.ID),
Until: deletedDecision.Until.String(),
Type: &deletedDecision.Type,
}
decisions = append(decisions, dec)
}View on GitHub (pinned to 909b515798)
Solutions
- Check database connectivity and logs for the underlying wrapped SQL error
- Verify the database schema is up to date (cscli migrations / version match)
- Retry the pull once the DB is healthy
- Check disk space and DB lock contention
Defensive patterns
Strategy: retry
Validate before calling
if err := p.DBClient.Ping(ctx); err != nil { return fmt.Errorf("database unavailable before expiring decisions") } Try / catch
if err := DecisionCmd(ctx, msg, p, false); err != nil { if strings.Contains(err.Error(), "unable to expire decisions") { /* retry with backoff; check DB health */ } } Prevention
- Monitor database connectivity and disk space
- Apply schema migrations before starting the service
- Avoid SQLite under high concurrency where possible
When it happens
Trigger: p.DBClient.ExpireDecisionsWithFilter returns an error — DB connectivity failure, SQL error, lock timeout, or an unsupported database backend.
Common situations: Database down or restarting (e.g. in a cluster), disk full, DB migration pending, SQLite lock contention under heavy load.
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
- while getting decision: %w
- '%s %s failed: %w
- message for '%s' contains bad data format: %w
- decision duration '%+v': %w: %w
- decision with alert ID '%d': %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/035372254796d1e0.
Report an issue: GitHub.