netbirdio/netbird · error

delete IP from ipset %s: %w

Error message

delete IP from ipset %s: %w

What it means

The delFromIPSet helper's netlink DEL of an entry failed. Common cases: the element is not in the set (ErrNotExist, typically a kernel/memory desync since callers check their own map first), the set itself is gone, the entry family mismatches the set, or privileges are missing. Appears wrapped by callers as 'delete ip from ipset: delete IP from ipset <name>: ...'.

Source

Thrown at client/firewall/iptables/acl_linux.go:591

		return fmt.Errorf("add IP to ipset %s: %w", name, err)
	}

	return nil
}

func (m *aclManager) delFromIPSet(name string, ip net.IP) error {
	cidr := uint8(32)
	if ip.To4() == nil {
		cidr = 128
	}

	entry := &ipset.Entry{
		IP:   ip,
		CIDR: cidr,
	}

	if err := ipset.Del(name, entry); err != nil {
		return fmt.Errorf("delete IP from ipset %s: %w", name, err)
	}

	return nil
}

func (m *aclManager) flushIPSet(name string) error {
	return ipset.Flush(name)
}

func (m *aclManager) destroyIPSet(name string) error {
	return ipset.Destroy(name)
}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Treat ErrNotExist (element or set) as success and continue.
  2. Recreate the set and retry when the whole set is missing and more operations follow.
  3. Verify family match and privileges before issuing deletes.
  4. Reconcile with Reset instead of hand-deleting after external changes.
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm presence before DEL to make the call idempotent
if err := ipset.Test(name, &ipset.Entry{IP: ip, CIDR: cidr}); err != nil {
    if errors.Is(err, ipset.ErrElementNotExist) || errors.Is(err, ipset.ErrSetNotExist) {
        // nothing to delete in the kernel; update local state only
    }
}

Try / catch

if err := mgr.DeletePeerRule(rule); err != nil {
    if strings.Contains(err.Error(), "delete IP from ipset") {
        if errors.Is(err, ipset.ErrElementNotExist) || errors.Is(err, ipset.ErrSetNotExist) {
            err = nil // desired state already holds
        }
    }
}

Prevention

When it happens

Trigger: DeletePeerRule after external `ipset flush`; deleting from a set already destroyed while the manager's ips map still lists the element; v4/v6 family mismatch on the Entry; non-root execution.

Common situations: Post-restart state where persisted maps outlive kernel sets; operators flushing ipsets; cleanup code running in a changed network namespace.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/999d8e3bfe3bf6c1. Report an issue: GitHub.