crowdsecurity/crowdsec · error

marking usage metrics as sent: %w

Error message

marking usage metrics as sent: %w

What it means

MarkUsageMetricsAsSent sets pushed_at on the metric rows with the given IDs. This error wraps a failing bulk UPDATE. Note the Save count is ignored, so a zero-row update is still 'success' — only a database-level failure produces this error.

Source

Thrown at pkg/database/metrics.go:71

			metric.PushedAtIsNil(),
		).
		All(ctx)
	if err != nil {
		c.Log.Warningf("GetBouncerUsageMetricsByName: %s", err)
		return nil, fmt.Errorf("getting bouncer usage metrics by name %s: %w", bouncerName, err)
	}

	return metrics, nil
}

func (c *Client) MarkUsageMetricsAsSent(ctx context.Context, ids []int) error {
	_, err := c.Ent.Metric.Update().
		Where(metric.IDIn(ids...)).
		SetPushedAt(time.Now().UTC()).
		Save(ctx)
	if err != nil {
		c.Log.Warningf("MarkUsageMetricsAsSent: %s", err)
		return fmt.Errorf("marking usage metrics as sent: %w", err)
	}

	return nil
}

// GetUnsentMetrics returns metrics not pushed to CAPI yet, across all sources, ordered by id.
// Callers walk the backlog by passing back the id of the last row they consumed.
func (c *Client) GetUnsentMetrics(ctx context.Context, afterID int, limit int) ([]*ent.Metric, error) {
	metrics, err := c.Ent.Metric.Query().
		Where(
			metric.PushedAtIsNil(),
			metric.IDGT(afterID),
		).
		Order(ent.Asc(metric.FieldID)).
		Limit(limit).
		All(ctx)
	if err != nil {
		c.Log.Warningf("GetUnsentMetrics: %s", err)

View on GitHub (pinned to 909b515798)

Solutions

  1. Check the Warningf log 'MarkUsageMetricsAsSent: <err>' for the real cause.
  2. Resolve writer contention (WAL mode / single crowdsec process per DB).
  3. Free disk space; verify the DB integrity.
  4. Re-run the send loop — unsent rows will be re-fetched by GetUnsentMetrics, so a failed mark just risks a duplicate push, not data loss.

Example fix

// before: error only
if err := c.MarkUsageMetricsAsSent(ctx, ids); err != nil { log.Error(err) }
// after: tolerate failure so push loop keeps going (rows may be pushed twice at worst)
if err := c.MarkUsageMetricsAsSent(ctx, ids); err != nil {
    log.Warnf("could not mark metrics sent, they may be re-pushed: %v", err)
}
Defensive patterns

Strategy: retry

Validate before calling

// ensure the ids are non-empty before issuing the update
if len(ids) == 0 { return nil }

Try / catch

err := client.MarkUsageMetricsAsSent(ctx, ids)
if err != nil {
    log.Warnf("mark-sent failed; rows may be re-pushed next cycle: %v", err)
    // do not abort the loop — at worst metrics get pushed twice
}

Prevention

When it happens

Trigger: Calling MarkUsageMetricsAsSent (from sendUsageMetricsBatch after a successful CAPI push) when the UPDATE fails: DB write lock held by another process, disk full, corrupted DB, or context cancellation.

Common situations: SQLite 'database is locked' while the agent writes alert rows concurrently; disk quota exceeded on the metrics volume after a large usage batch.

Related errors


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