crowdsecurity/crowdsec · error
unable to delete bouncers: %w
Error message
unable to delete bouncers: %w
What it means
BulkDeleteBouncers wraps a failed ent batch delete of bouncer rows. The delete runs `DELETE FROM bouncers WHERE id IN (...)` against the configured database; any driver-level or context failure is wrapped with this message. Callers (e.g. prune) get the count plus this error.
Source
Thrown at pkg/database/bouncers.go:126
return err
}
if nbDeleted == 0 {
return &BouncerNotFoundError{BouncerName: name}
}
return nil
}
func (c *Client) BulkDeleteBouncers(ctx context.Context, bouncers []*ent.Bouncer) (int, error) {
ids := make([]int, len(bouncers))
for i, b := range bouncers {
ids[i] = b.ID
}
nbDeleted, err := c.Ent.Bouncer.Delete().Where(bouncer.IDIn(ids...)).Exec(ctx)
if err != nil {
return nbDeleted, fmt.Errorf("unable to delete bouncers: %w", err)
}
return nbDeleted, nil
}
func (c *Client) UpdateBouncerLastPull(ctx context.Context, lastPull time.Time, id int) error {
_, err := c.Ent.Bouncer.UpdateOneID(id).
SetLastPull(lastPull).
Save(ctx)
if err != nil {
return fmt.Errorf("unable to update machine last pull in database: %w", err)
}
return nil
}
func (c *Client) UpdateBouncerStreamPull(ctx context.Context, lastPull time.Time, streamCursor int, id int) error {
_, err := c.Ent.Bouncer.UpdateOneID(id).View on GitHub (pinned to 909b515798)
Solutions
- Check database connectivity and that no other process holds a lock on the SQLite file
- Inspect the wrapped %w error for the driver-level cause (retry on transient network errors)
- Verify the context (timeout/cancellation) is generous enough for batch deletes
- Run database integrity checks / backup-restore if the DB is corrupted
Example fix
// before
nbDeleted, err := c.Ent.Bouncer.Delete().Where(bouncer.IDIn(ids...)).Exec(ctx)
// after
nbDeleted, err := c.Ent.Bouncer.Delete().Where(bouncer.IDIn(ids...)).Exec(ctx)
if ent.IsNotFound(err) {
return nbDeleted, nil // nothing left to delete
} Defensive patterns
Strategy: retry
Validate before calling
// caller-side: verify DB reachable before bulk delete
if err := client.PingDB(ctx); err != nil { return fmt.Errorf("db unavailable: %w", err) } Try / catch
nbDeleted, err := c.BulkDeleteBouncers(ctx, bouncers)
if err != nil {
var rec errtypes.ErrRetryable
if errors.As(err, &rec) { /* retry with backoff */ }
return fmt.Errorf("prune aborted: %w", err)
} Prevention
- Keep prune contexts generous; avoid cancelling mid-batch
- Enable SQLite WAL mode to reduce lock contention
- Monitor DB connectivity before maintenance jobs
- Backup the DB before bulk deletes
When it happens
Trigger: Database unavailable/corrupted, context cancelled during delete, foreign key or driver constraint failure while removing the bouncer IDs gathered by QueryBouncers.
Common situations: cscli/prune deleting stale bouncers when the SQLite file is locked by another process, MySQL connection dropped mid-batch, context deadline exceeded on slow disks.
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
- unable to update machine last pull in database: %w
- unable to update bouncer stream pull in database: %w
- while getting allowlist %s: %s
- unable to update bouncer ip address in database: %w
- unable to update bouncer type and version in database: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/6bc0006e0c4dbb10.
Report an issue: GitHub.