crowdsecurity/crowdsec · error · DeleteFail
delete lock: %w: %w
Error message
delete lock: %w: %w
What it means
The ent DELETE on the lock table failed while releasing the named lock in ReleaseLock. The sentinel DeleteFail is double-wrapped with the driver error; the distributed lock stays held until its TTL/timeout path (ReleaseLockWithTimeout) or manual cleanup intervenes.
Source
Thrown at pkg/database/lock.go:41
SetCreatedAt(time.Now().UTC()).
Save(ctx)
if ent.IsConstraintError(err) {
return err
}
if err != nil {
return fmt.Errorf("insert lock: %w: %w", err, InsertFail)
}
return nil
}
func (c *Client) ReleaseLock(ctx context.Context, name string) error {
log.Debugf("releasing lock %s", name)
_, err := c.Ent.Lock.Delete().Where(lock.NameEQ(name)).Exec(ctx)
if err != nil {
return fmt.Errorf("delete lock: %w: %w", err, DeleteFail)
}
return nil
}
func (c *Client) ReleaseLockWithTimeout(ctx context.Context, name string, timeout int) error {
log.Debugf("releasing lock %s with timeout of %d minutes", name, timeout)
_, err := c.Ent.Lock.Delete().Where(
lock.NameEQ(name),
lock.CreatedAtLT(time.Now().UTC().Add(-time.Duration(timeout)*time.Minute)),
).Exec(ctx)
if err != nil {
return fmt.Errorf("delete lock: %w: %w", err, DeleteFail)
}
return nil
}View on GitHub (pinned to 909b515798)
Solutions
- Verify DB connectivity; a leaked lock row can be removed manually: `DELETE FROM locks WHERE name='...'`
- Retry ReleaseLock — deletion is idempotent
- Inspect wrapped driver error for table/permission issues
- Ensure the process shutdown path gives the DB time to flush before exit
Example fix
// manual recovery sqlite3 /var/lib/crowdsec/data/crowdsec.db "DELETE FROM locks WHERE name='CapiPull';"
Defensive patterns
Strategy: try-catch
Validate before calling
exists, _ := c.Ent.Lock.Query().Where(lock.NameEQ(name)).Exist(ctx) // check before release
Try / catch
if err := c.ReleaseLock(ctx, name); err != nil {
log.Warnf("lock %s may be leaked: %v", name, err)
// schedule manual cleanup
} Prevention
- Always defer ReleaseLock right after AcquireLock succeeds
- Alert on leaked lock rows in the locks table
- Give shutdown handlers enough time to reach the DB
When it happens
Trigger: `c.Ent.Lock.Delete().Where(lock.NameEQ(name)).Exec(ctx)` returns an error — DB connection lost, ctx canceled, or locks table inaccessible while releasing an acquired lock.
Common situations: CAPI pull finishing while the database is shutting down; network drop between crowdsec and external DB mid-operation; stale lock cleanup hitting a broken connection.
Related errors
- insert lock: %w: %w
- while getting allowlist %s: %s
- while getting alert: %w
- while getting decision: %w
- unable to query alerts for uuid %s: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/24953eeba46a237a.
Report an issue: GitHub.