crowdsecurity/crowdsec · error

while saving alert from blocklist %s: %w

Error message

while saving alert from blocklist %s: %w

What it means

Wraps errors returned by a.SaveAlerts when persisting the alert built from the pulled blocklist decisions. SaveAlerts writes the alert plus decisions (and optional counters) to the database, so the wrapped error is a DB write failure during blocklist import.

Source

Thrown at pkg/apiserver/apic.go:1003

	err = a.dbClient.SetConfigItem(ctx, blocklistConfigItemName, time.Now().UTC().Format(http.TimeFormat))
	if err != nil {
		return fmt.Errorf("while setting last pull timestamp for blocklist %s: %w", *blocklist.Name, err)
	}

	if len(decisions) == 0 {
		log.Infof("blocklist %s has no decisions", *blocklist.Name)
		return nil
	}
	// apply APIC specific whitelists
	decisions = a.ApplyApicWhitelists(ctx, decisions)
	alert := createAlertForDecision(decisions[0], types.CAPIAlertKind)
	alertsFromCapi := []*models.Alert{alert}
	alertsFromCapi = fillAlertsWithDecisions(alertsFromCapi, decisions, addCounters)

	err = a.SaveAlerts(ctx, alertsFromCapi, addCounters, nil)
	if err != nil {
		return fmt.Errorf("while saving alert from blocklist %s: %w", *blocklist.Name, err)
	}

	return nil
}

func (a *apic) UpdateBlocklists(ctx context.Context, blocklists []*modelscapi.BlocklistLink, addCounters map[string]map[string]int, forcePull bool) error {
	if len(blocklists) == 0 {
		return nil
	}

	// we must use a different http client than apiClient's because the transport of apiClient is jwtTransport or here we have signed apis that are incompatibles
	// we can use the same baseUrl as the urls are absolute and the parse will take care of it
	defaultClient, err := apiclient.NewDefaultClient(a.apiClient.BaseURL, "", "", nil)
	if err != nil {
		return fmt.Errorf("while creating default client: %w", err)
	}

	for _, blocklist := range blocklists {

View on GitHub (pinned to 909b515798)

Solutions

  1. Read the inner error from SaveAlerts for the specific DB cause.
  2. Enable WAL mode: `cscli db enable-wal`; run `cscli db doctor`.
  3. Check disk space and DB connectivity.
  4. Retry the pull cycle; alerts are idempotent per blocklist alert.
Defensive patterns

Strategy: retry

Validate before calling

// pre-check: cscli db doctor && cscli db enable-wal

Try / catch

if err := a.SaveAlerts(ctx, alertsFromCapi, addCounters, nil); err != nil {
    log.Warnf("saving blocklist alert failed, will retry next pull: %v", err)
    return err
}

Prevention

When it happens

Trigger: updateBlocklist fetched non-empty decisions, builds createAlertForDecision(...CAPIAlertKind) and calls SaveAlerts; the insert fails due to DB outage, context timeout, SQLite lock, or malformed decision data.

Common situations: Large blocklist insert exceeding SQLite lock timeout without WAL, PostgreSQL connection drop, disk full, context cancelled by shutdown during pull.

Related errors


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