istio/istio · error
failed to add IP %s to ipset %s: %w
Error message
failed to add IP %s to ipset %s: %w
What it means
A thin wrapper around netlink.IpsetAdd: adding an IP entry to a kernel ipset failed. '%s'/'%s' are the IP and set name; '%w' carries the netlink error. In istio-cni these sets (e.g. istio-in-pod/istio-out-pod for ambient interception) drive pod traffic redirect, so failures degrade traffic capture.
Source
Thrown at cni/pkg/ipset/nldeps_linux.go:72
return nil
}
return err
}
func (m *realDeps) destroySet(name string) error {
err := netlink.IpsetDestroy(name)
return err
}
func (m *realDeps) addIP(name string, ip netip.Addr, ipProto uint8, comment string, replace bool) error {
err := netlink.IpsetAdd(name, &netlink.IPSetEntry{
Comment: comment,
IP: net.IP(ip.AsSlice()),
Protocol: &ipProto,
Replace: replace,
})
if err != nil {
return fmt.Errorf("failed to add IP %s to ipset %s: %w", ip, name, err)
}
return nil
}
func (m *realDeps) deleteIP(name string, ip netip.Addr, ipProto uint8) error {
err := netlink.IpsetDel(name, &netlink.IPSetEntry{
IP: net.IP(ip.AsSlice()),
Protocol: &ipProto,
})
if err != nil {
return fmt.Errorf("failed to delete IP %s from ipset %s: %w", ip, name, err)
}
return nil
}
func (m *realDeps) flush(name string) error {
err := netlink.IpsetFlush(name)
if err != nil {View on GitHub (pinned to 8dc789c5cf)
Solutions
- Inspect the wrapped netlink error: 'Set cannot be added to' / 'already exists' points to ordering; recreate the set (ipset destroy istio-in-pod; the node agent recreates it).
- If 'already exists', ensure callers pass replace=true where re-adding is expected, or clear stale entries first (the wrapper supports comment-based clearing).
- Verify the ipset exists before adding: ipset list istio-in-pod.
- Check capabilities: the pod needs CAP_NET_ADMIN; on old kernels upgrade or drop the comment feature.
Example fix
// before err := m.addIP(setName, ip, 0x06, comment, false) // after: tolerate re-adds during pod churn err := m.addIP(setName, ip, 0x06, comment, true)
Defensive patterns
Strategy: retry
Validate before calling
ipset list istio-in-pod >/dev/null 2>&1 || echo "set missing; create before adding entries"
Try / catch
// Retry once after recreating the set, idempotently.
if err := deps.AddIP(set, ip, proto, comment, true); err != nil {
if isNotExist(err) {
_ = deps.Create(set) // recreate then retry once
err = deps.AddIP(set, ip, proto, comment, true)
}
if err != nil { /* log and surface */ }
} Prevention
- Always create the ipset before adding entries (create-then-add ordering).
- Pass replace=true for idempotent re-adds during pod churn.
- Keep CAP_NET_ADMIN on the node agent and protect sets from external destroy.
When it happens
Trigger: realDeps.addIP is called (e.g. when a pod is added to an ambient mesh and its IP must be inserted) and the kernel rejects the netlink IPSET_CMD_ADD: set does not exist, entry already exists without replace, protocol mismatch (IPv4 entry into IPv6 set), or permission/netlink communication failure.
Common situations: ipsetCreate was skipped or the set was destroyed concurrently by another agent (iptables-legacy tools, a node cleanup job); kernel ipset revision too old for the 'comment' feature (see the Alpine note in the same file); running without CAP_NET_ADMIN; race between pod deletion and re-add where replace=false and the entry already exists.
Related errors
- failed to delete IP %s from ipset %s: %w
- failed to flush ipset %s: %w
- failed to list ipset %s: %w
- v4 IPset detection failed: %w
- failed to parse ambient enablement selector: %v
AI-assisted analysis of istio/istio@8dc789c5cf (2026-08-15).
Data as JSON: /api/errors/2d3d9810817c5f2f.
Report an issue: GitHub.