crowdsecurity/crowdsec · error
unable to add values to allowlist: %w
Error message
unable to add values to allowlist: %w
What it means
ReplaceAllowlist first deletes all existing items of an allowlist, then re-adds the new set via AddToAllowlist. When the re-insert phase fails (DB insert error, invalid value, constraint violation), the deletion has already committed, so the error means the allowlist may be left empty. It wraps the underlying ent/SQLite error with this message.
Source
Thrown at pkg/database/allowlists.go:229
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
}
// IsAllowlistedBy returns a list of human-readable reasons explaining which allowlists
// the given value (IP or CIDR) matches.
//
// Few cases:View on GitHub (pinned to 909b515798)
Solutions
- Inspect the wrapped error (%w) to find the root cause - usually a DB constraint or lock error
- Verify the incoming AllowlistItem values are valid IPs/CIDRs before calling ReplaceAllowlist
- Check for concurrent crowdsec/cscli processes holding the SQLite lock; stop others and retry
- Re-run ReplaceAllowlist: it is idempotent since it deletes then re-adds all items
Example fix
// before
c.Log.Debugf("replacing values in allowlist %s", list.Name)
added, err := c.AddToAllowlist(ctx, list, items)
// after - validate values first so a bad item does not empty the list
for _, it := range items {
if _, err := csnet.NewRange(it.Value); err != nil {
return 0, fmt.Errorf("invalid allowlist value %q: %w", it.Value, err)
}
}
added, err := c.AddToAllowlist(ctx, list, items) Defensive patterns
Strategy: try-catch
Validate before calling
for _, it := range items {
if _, err := csnet.NewRange(it.Value); err != nil {
return fmt.Errorf("invalid allowlist value %q: %w", it.Value, err)
}
} Try / catch
added, err := c.ReplaceAllowlist(ctx, list, items, fromConsole)
if err != nil {
if strings.Contains(err.Error(), "database is locked") {
// back off and retry the whole replace; it is idempotent
}
return fmt.Errorf("replace allowlist %s failed, list may be empty: %w", list.Name, err)
} Prevention
- Validate item values are parseable IPs/CIDRs before calling ReplaceAllowlist
- Avoid running concurrent cscli writes and daemon allowlist syncs on SQLite
- Treat a failed replace as potentially destructive: re-run it rather than leaving the list empty
When it happens
Trigger: Calling ReplaceAllowlist (e.g. via updateOneAllowlist when the console pulls allowlist updates) where AddToAllowlist fails: malformed allowlist item value that fails parsing, duplicate value hitting a uniqueness constraint, or the database being locked/unavailable.
Common situations: Console-managed allowlist sync pulling items with unexpected formats; concurrent crowdsec processes writing to the SQLite DB causing 'database is locked'; a corrupted DB schema after an upgrade.
Related errors
- while getting allowlist %s: %s
- while creating allowlist %s: %s
- unable to expire decisions for list %s : %w
- %s: %w
- bulk creating alert: %w: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/ee416c1667ab54e6.
Report an issue: GitHub.