netbirdio/netbird · error

create ipset %s: %w

Error message

create ipset %s: %w

What it means

This is the createIPSet helper: a netlink CREATE of a hash:net set (Replace:true, FamilyIPV6 when m.v6) failed. It fails without CAP_NET_ADMIN, when ip_set/ip_set_hash_net modules are absent, or on an invalid name (ipset caps names at 31 characters). Callers wrap it again (error 481), so logs can show 'create ipset: create ipset <name>: ...' with the inner message carrying the netlink errno.

Source

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

	defer func() {
		if err := ipset.Destroy(probeName); err != nil {
			log.Debugf("destroy ipset probe set %q: %v", probeName, err)
		}
	}()

	return true
}

func (m *aclManager) createIPSet(name string) error {
	opts := ipset.CreateOptions{
		Replace: true,
	}
	if m.v6 {
		opts.Family = ipset.FamilyIPV6
	}

	if err := ipset.Create(name, ipset.TypeHashNet, opts); err != nil {
		return fmt.Errorf("create ipset %s: %w", name, err)
	}

	log.Debugf("created ipset %s with type hash:net", name)
	return nil
}

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

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

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Run as root / grant CAP_NET_ADMIN and CAP_NET_MODULE.
  2. Pre-load ip_set and ip_set_hash_net at boot or image build.
  3. Keep set names <=31 characters.
  4. If modules genuinely cannot load, disable the ipset path so the manager falls back to per-IP rules.
Defensive patterns

Strategy: try-catch

Validate before calling

func ensureIPSetCreatePossible(name string) error {
    if len(name) > 31 {
        return fmt.Errorf("ipset name %q exceeds 31-char limit", name)
    }
    if os.Geteuid() != 0 {
        return errors.New("ipset CREATE requires CAP_NET_ADMIN")
    }
    if _, err := os.Stat("/proc/net/ipset"); err != nil {
        return errors.New("ipset subsystem unavailable (modprobe ip_set)")
    }
    return nil
}

Try / catch

if err := mgr.AddPeerFiltering(...); err != nil {
    if strings.Contains(err.Error(), "create ipset") {
        // EPERM -> privileges; missing module -> load ip_set_hash_net; long name -> shorten
        log.Errorf("ipset create failed: %v", err)
    }
}

Prevention

When it happens

Trigger: First use of a new ruleset ipset on a host lacking the ipset kernel modules; unprivileged agent; generated set name over 31 chars; kernel namespace where netlink CREATE is filtered by seccomp/AppArmor.

Common situations: Minimal VM images and containers without module auto-load; long peer-group-derived set names; security-hardened deployments restricting netlink.

Related errors


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