crowdsecurity/crowdsec · error

unable to delete allowlist contents: %w

Error message

unable to delete allowlist contents: %w

What it means

ReplaceAllowlist first deletes ALL existing items of the target allowlist, then re-adds the provided set. If the initial bulk delete of the contents fails, it returns 'unable to delete allowlist contents: %w'. Because the delete runs outside a transaction together with the re-add, a failure here can leave the allowlist emptied if AddToAllowlist subsequently fails.

Source

Thrown at pkg/database/allowlists.go:224

func (c *Client) UpdateAllowlistMeta(ctx context.Context, allowlistID string, name string, description string) error {
	c.Log.Debugf("updating allowlist %s meta", name)

	err := c.Ent.AllowList.Update().Where(allowlist.AllowlistIDEQ(allowlistID)).SetName(name).SetDescription(description).Exec(ctx)
	if err != nil {
		return fmt.Errorf("unable to update allowlist: %w", err)
	}

	return nil
}

func (c *Client) ReplaceAllowlist(ctx context.Context, list *ent.AllowList, items []*models.AllowlistItem, fromConsole bool) (int, error) {
	c.Log.Debugf("replacing values in allowlist %s", list.Name)
	c.Log.Tracef("items: %+v", items)

	_, err := c.Ent.AllowListItem.Delete().Where(allowlistitem.HasAllowlistWith(allowlist.IDEQ(list.ID))).Exec(ctx)
	if err != nil {
		return 0, fmt.Errorf("unable to delete allowlist contents: %w", err)
	}

	added, err := c.AddToAllowlist(ctx, list, items)
	if err != nil {
		return 0, fmt.Errorf("unable to add values to allowlist: %w", err)
	}

	if !list.FromConsole && fromConsole {
		c.Log.Infof("marking allowlist %s as managed from console and replacing its content", list.Name)

		err = c.Ent.AllowList.Update().SetFromConsole(fromConsole).Where(allowlist.IDEQ(list.ID)).Exec(ctx)
		if err != nil {
			return 0, fmt.Errorf("unable to update allowlist: %w", err)
		}
	}

	return added, nil
}

View on GitHub (pinned to 909b515798)

Solutions

  1. Inspect the wrapped driver error and fix the DB-level cause (connectivity, locks, disk space)
  2. After a failure, verify allowlist contents — the delete may have partially applied; re-run ReplaceAllowlist to reach a consistent state
  3. Reduce concurrent DB writers or move from SQLite to MySQL/Postgres to avoid lock contention
  4. Retry the replace once the database is healthy; the operation is idempotent since it deletes before inserting
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := client.GetAllowListByID(ctx, list.AllowlistID, false); err != nil {
    return fmt.Errorf("target allowlist unavailable: %w", err)
}

Try / catch

added, err := client.ReplaceAllowlist(ctx, list, items, fromConsole)
if err != nil && strings.Contains(err.Error(), "unable to delete allowlist contents") {
    // DB-level delete failure; contents may be partially deleted — re-run ReplaceAllowlist after fixing the DB
}

Prevention

When it happens

Trigger: Client.ReplaceAllowlist (called from updateOneAllowlist during console sync) when the DELETE on allowlist_items fails: DB unreachable, locked, corrupted table, or cancelled context.

Common situations: Console allowlist sync against a database that went down or is locked (SQLite concurrent writers); disk full preventing the delete; interrupted network to a remote MySQL/Postgres.

Related errors


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