cilium/cilium · error
failed to list ipset %s: %w
Error message
failed to list ipset %s: %w
What it means
Returned by ipset.list when the external `ipset list <name>` command exits non-zero (pkg/datapath/iptables/ipset/ipset.go:237). The wrapper error carries the set name and the underlying exec error, so a missing ipset binary, a nonexistent set, or a permission/kernel problem all surface here. In Cilium's reconcile flow (reconcile -> list) this aborts diffing current set members against desired state.
Source
Thrown at pkg/datapath/iptables/ipset/ipset.go:237
}
return nil
}
func (i *ipset) remove(ctx context.Context, name string) error {
if _, err := i.run(ctx, "list", name); err != nil {
// ipset does not exist, nothing to remove
return nil
}
if _, err := i.run(ctx, "destroy", name); err != nil {
return fmt.Errorf("failed to remove ipset %s: %w", name, err)
}
return nil
}
func (i *ipset) list(ctx context.Context, name string) (AddrSet, error) {
out, err := i.run(ctx, "list", name)
if err != nil {
return AddrSet{}, fmt.Errorf("failed to list ipset %s: %w", name, err)
}
addrs := AddrSet{}
scanner := bufio.NewScanner(bytes.NewReader(out))
for scanner.Scan() {
line := scanner.Text()
addr, err := netip.ParseAddr(line)
if err != nil {
continue
}
addrs = addrs.Insert(addr)
}
if err := scanner.Err(); err != nil {
return AddrSet{}, fmt.Errorf("failed to scan ipset %s: %w", name, err)
}
return addrs, nil
}
View on GitHub (pinned to ac7b90affa)
Solutions
- Verify the `ipset` binary exists and works on the host (`ipset --version`) and is present in the agent image
- Run the agent as root / with NET_ADMIN capability and confirm `lsmod | grep ip_set` shows the kernel modules
- If the set may legitimately not exist, check existence first (or handle the 'does not exist' exit code) before listing, as ipset.remove does
- Inspect the wrapped %w error from exec to distinguish binary-not-found vs command failure
- Retry the reconcile; Prune re-runs on next startup once the environment is fixed
Example fix
// before
curSet, err := ipset.list(ctx, name)
if err != nil {
return fmt.Errorf("unable to list ipset %s: %w", name, err)
}
// after: tolerate a not-yet-created set by creating it first (reconcile already does)
if err := ipset.create(ctx, name, string(family)); err != nil {
return fmt.Errorf("unable to create ipset %s: %w", name, err)
}
curSet, err := ipset.list(ctx, name) Defensive patterns
Strategy: try-catch
Validate before calling
cmd := exec.Command("ipset", "list", name)
if err := cmd.Run(); err != nil {
return fmt.Errorf("ipset %s not listable: %w", name, err)
} Type guard
func isExecNotFound(err error) bool {
var ee *exec.Error
return errors.As(err, &ee) && errors.Is(ee.Err, exec.ErrNotFound)
} Try / catch
curSet, err := ipset.list(ctx, name)
if err != nil {
var ee *exec.Error
if errors.As(err, &ee) {
log.Fatalf("ipset binary missing: %v", err)
}
return fmt.Errorf("skipping reconcile of %s: %w", name, err)
} Prevention
- Ship the ipset binary in the agent image and smoke-test `ipset --version` at startup
- Run with CAP_NET_ADMIN and verify ip_set kernel modules are loaded before reconcile
- Check set existence (or use -exist create) before listing
- Log the wrapped exec error, not just the wrapper, to speed diagnosis
When it happens
Trigger: `ipset list <name>` fails: the ipset executable is missing or not in PATH, the named set does not exist, the caller lacks CAP_NET_ADMIN/root, the kernel ipset module is not loaded, or the command times out / context is canceled.
Common situations: Cilium agent container without ipset binary or NET_ADMIN capability; host kernel without ip_set modules; stale iptables rules referencing a deleted set; tests (TestIPSetListInexistentIPSet) probing a set that was never created.
Related errors
- unable to create ipset %s: %w
- unable to list ipset %s: %w
- unable to delete from ipset: %w
- failed to scan ipset %s: %w
- no link found inside container
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/a831954b53b5aff7.
Report an issue: GitHub.