netbirdio/netbird · error
create set %s: %w
Error message
create set %s: %w
What it means
Returned by router.createIpSet in the NetBird iptables firewall manager when the kernel refuses to create an ipset. It wraps createIPSet, which calls ipset.Create (lrh3321/ipset-go, netlink) with TypeHashNet, Replace:true and FamilyIPV6 on the v6 router. Creating a set requires root privileges (CAP_NET_ADMIN), the nfnetlink/ip_set/ip_set_hash_net kernel modules, and a valid set name (kernel limit 31 chars).
Source
Thrown at client/firewall/iptables/router_linux.go:244
}
}
return nberrors.FormatErrorOrNil(merr)
}
func (r *router) findSets(rule []string) []string {
var sets []string
for i, arg := range rule {
if arg == "-m" && i+3 < len(rule) && rule[i+1] == "set" && rule[i+2] == matchSet {
sets = append(sets, rule[i+3])
}
}
return sets
}
func (r *router) createIpSet(setName string, sources []netip.Prefix) error {
if err := r.createIPSet(setName); err != nil {
return fmt.Errorf("create set %s: %w", setName, err)
}
for _, prefix := range sources {
if err := r.addPrefixToIPSet(setName, prefix); err != nil {
return fmt.Errorf("add element to set %s: %w", setName, err)
}
}
return nil
}
func (r *router) deleteIpSet(setName string) error {
if err := r.destroyIPSet(setName); err != nil {
return fmt.Errorf("destroy set %s: %w", setName, err)
}
log.Debugf("Deleted unused ipset %s", setName)
return nilView on GitHub (pinned to 93e97f4bf1)
Solutions
- Run the agent as root, and in containers add NET_ADMIN (docker run --cap-add NET_ADMIN)
- Load kernel modules: modprobe nfnetlink ipset ip_set_hash_net (or check CONFIG_IP_SET in kernel config)
- Verify manual creation works: sudo ipset create probe hash:net && sudo ipset destroy probe
- Check dmesg/journal for netlink 'Operation not permitted' or 'No such file or directory' module errors
- Confirm no other netbird instance already owns the set names (ipset list -t)
Example fix
# before: container without netfilter rights docker run netbird/netbird up # after docker run --cap-add NET_ADMIN --sysctl net.ipv4.ip_forward=1 netbird/netbird up
Defensive patterns
Strategy: validation
Validate before calling
// probe ipset support before starting the route firewall
func ipsetAvailable() error {
if os.Geteuid() != 0 {
return fmt.Errorf("agent must run as root for ipset management")
}
const probe = "nb-probe-set"
if err := ipset.Create(probe, ipset.TypeHashNet, ipset.CreateOptions{Replace: true}); err != nil {
return fmt.Errorf("ipset create probe: %w", err)
}
return ipset.Destroy(probe)
} Prevention
- Run containers with --cap-add NET_ADMIN and the agent as root
- Preload nfnetlink/ipset/ip_set_hash_net modules in minimal images
- Check 'lsmod | grep ip_set' or a manual 'ipset create probe hash:net' as a preflight in deployment scripts
- Keep set names within the kernel's 31-character ipset name limit
When it happens
Trigger: AddRouteFiltering (or refcounter.Increment from UpdateSet) with more than one source prefix makes the router create a 'nb-route-<id>[-v6]' hash:net set. It fails when: the agent lacks CAP_NET_ADMIN (container without NET_ADMIN, or not run via sudo); the ipset kernel modules/CONFIG_IP_SET are absent; netlink is unavailable in the sandbox; or the generated name exceeds the kernel ipset name limit.
Common situations: Running netbird up in Docker/LXC without --cap-add NET_ADMIN; minimal cloud/WSL2 kernels without ipset modules; hosts where ipset was never loaded (verify with 'lsmod | grep ip_set'); environments where a third party already created a conflicting set name.
Related errors
- add IP to ipset: %w
- create ipset: %w
- failed to check rule: %w
- create ipset %s: %w
- add IP to ipset %s: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/944da2d9857ddce7.
Report an issue: GitHub.