crowdsecurity/crowdsec · warning
unable to update base bouncer metrics in database: %w
Error message
unable to update base bouncer metrics in database: %w
What it means
BouncerUpdateBaseMetrics persists bouncer telemetry (OS family/version, feature flags, bouncer type) via an ent Bouncer update. If the Save fails, this error wraps the DB failure. The bouncer's auth still works; only metrics recording failed.
Source
Thrown at pkg/database/bouncers.go:37
return fmt.Sprintf("'%s' does not exist", e.BouncerName)
}
func (c *Client) BouncerUpdateBaseMetrics(ctx context.Context, bouncerName string, bouncerType string, baseMetrics models.BaseMetrics) error {
os := baseMetrics.Os
features := strings.Join(baseMetrics.FeatureFlags, ",")
_, err := c.Ent.Bouncer.
Update().
Where(bouncer.NameEQ(bouncerName)).
SetNillableVersion(baseMetrics.Version).
SetOsname(*os.Name).
SetOsfamily(os.Family).
SetOsversion(*os.Version).
SetFeatureflags(features).
SetType(bouncerType).
Save(ctx)
if err != nil {
return fmt.Errorf("unable to update base bouncer metrics in database: %w", err)
}
return nil
}
func (c *Client) SelectBouncers(ctx context.Context, apiKeyHash string, authType string) ([]*ent.Bouncer, error) {
// Order by ID so manually created bouncer will be first in the list to use as the base name
// when automatically creating a new entry if API keys are shared
result, err := c.Ent.Bouncer.Query().Where(bouncer.APIKeyEQ(apiKeyHash), bouncer.AuthTypeEQ(authType)).Order(ent.Asc(bouncer.FieldID)).All(ctx)
if err != nil {
return nil, err
}
return result, nil
}
func (c *Client) SelectBouncerWithIP(ctx context.Context, apiKeyHash string, clientIP string) (*ent.Bouncer, error) {
result, err := c.Ent.Bouncer.Query().Where(bouncer.APIKeyEQ(apiKeyHash), bouncer.IPAddressEQ(clientIP)).First(ctx)View on GitHub (pinned to 909b515798)
Solutions
- Verify the bouncer still exists ('cscli bouncers list'); re-auth re-creates missing rows
- Check the wrapped error for 'database is locked' and reduce concurrent writers
- Have the bouncer re-authenticate - metrics update is retried on each auth
Defensive patterns
Strategy: fallback
Validate before calling
if _, err := c.SelectBouncers(ctx, apiKeyHash, authType); err != nil {
// bouncer row gone; auth flow will re-create it before metrics update
} Try / catch
if err := c.BouncerUpdateBaseMetrics(ctx, bouncerID, os, features, bouncerType); err != nil {
c.Log.Warnf("bouncer metrics update failed (auth unaffected): %v", err)
return nil // do not fail authentication for a metrics bookkeeping error
} Prevention
- Don't delete a bouncer while it is actively authenticating
- Log metrics-update failures as warnings; they don't affect auth
- Metrics are re-sent on every bouncer auth, so transient failures self-heal
When it happens
Trigger: Calling BouncerUpdateBaseMetrics (from updateBaseMetrics, on bouncer auth) when the ent update fails: the bouncer row was deleted concurrently, DB locked, or IO error.
Common situations: A bouncer authenticating at the same moment an admin deletes it via 'cscli bouncers delete'; heavy SQLite write load from the daemon.
Related errors
- unable to create bouncer: %w
- unable to update base machine metrics in database: %w
- while getting allowlist %s: %s
- while getting alert: %w
- while getting decision: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/b1be815ff1de5557.
Report an issue: GitHub.