crowdsecurity/crowdsec · error · InsertFail

insert lock: %w: %w

Error message

insert lock: %w: %w

What it means

AcquireLock wraps the error from inserting a row into the locks table, additionally tagging it with InsertFail. Constraint errors are returned unwrapped; everything else means the lock could not be persisted.

Source

Thrown at pkg/database/lock.go:31

const (
	CAPIPullLockTimeout = 10
	CapiPullLockName    = "pullCAPI"
)

func (c *Client) AcquireLock(ctx context.Context, name string) error {
	log.Debugf("acquiring lock %s", name)
	_, err := c.Ent.Lock.Create().
		SetName(name).
		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)

View on GitHub (pinned to 909b515798)

Solutions

  1. Check DB connectivity before LAPI/CAPI operations
  2. Run `cscli hubtool` / `crowdsec -t` and ensure migrations ran (`cscli db migrate` equivalent — schema up to date)
  3. Check `errors.Is(err, database.InsertFail)` in the caller to distinguish insert failure from other causes
  4. Retry lock acquisition; it is safe to re-attempt

Example fix

// before
err := c.AcquireLock(ctx, name)
// after
if err := c.AcquireLock(ctx, name); err != nil {
    if database.IsLocked(err) { return nil } // held elsewhere
    if errors.Is(err, database.InsertFail) { log.Warn("db insert failed, retry later") }
    return err
}
Defensive patterns

Strategy: retry

Validate before calling

// verify schema has the locks table
ok, _ := c.Ent.Lock.Query().Limit(1).Exist(ctx)

Try / catch

if err := c.AcquireLock(ctx, name); err != nil {
    if database.IsLocked(err) { /* lock held elsewhere */ }
    if errors.Is(err, database.InsertFail) { /* db insert failure, retry later */ }
}

Prevention

When it happens

Trigger: `c.Ent.Lock.Create().SetName(name).Save(ctx)` fails with something other than a constraint error — DB unavailable, ctx canceled, or the locks table missing/corrupt.

Common situations: CAPI pull startup when MySQL/Postgres is unreachable; database schema out of date (missing locks table after partial migration); ctx deadline during LAPI startup.

Related errors


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