{"record":{"id":"509cc3c591bf3500","repo":"netbirdio/netbird","slug":"add-element-to-set-s-w","errorCode":null,"errorMessage":"add element to set %s: %w","messagePattern":"add element to set (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/firewall/iptables/router_linux.go","lineNumber":249,"sourceCode":"\nfunc (r *router) findSets(rule []string) []string {\n\tvar sets []string\n\tfor i, arg := range rule {\n\t\tif arg == \"-m\" && i+3 < len(rule) && rule[i+1] == \"set\" && rule[i+2] == matchSet {\n\t\t\tsets = append(sets, rule[i+3])\n\t\t}\n\t}\n\treturn sets\n}\n\nfunc (r *router) createIpSet(setName string, sources []netip.Prefix) error {\n\tif err := r.createIPSet(setName); err != nil {\n\t\treturn fmt.Errorf(\"create set %s: %w\", setName, err)\n\t}\n\n\tfor _, prefix := range sources {\n\t\tif err := r.addPrefixToIPSet(setName, prefix); err != nil {\n\t\t\treturn fmt.Errorf(\"add element to set %s: %w\", setName, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (r *router) deleteIpSet(setName string) error {\n\tif err := r.destroyIPSet(setName); err != nil {\n\t\treturn fmt.Errorf(\"destroy set %s: %w\", setName, err)\n\t}\n\n\tlog.Debugf(\"Deleted unused ipset %s\", setName)\n\treturn nil\n}\n\n// AddNatRule inserts an iptables rule pair into the nat chain\nfunc (r *router) AddNatRule(pair firewall.RouterPair) error {\n\tif r.legacyManagement {","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/firewall/iptables/router_linux.go#L231-L267","documentation":"Returned by router.createIpSet when ipset.Add fails for one of the route prefixes. addPrefixToIPSet builds an ipset.Entry{IP, CIDR, Replace:true} and calls the netlink add. The kernel rejects entries whose address family differs from the set family, entries with invalid CIDR bits, or when the set vanished mid-run.","triggerScenarios":"AddRouteFiltering/UpdateSet iterates the route's source prefixes after creating the set. A v4 prefix added to a set created with FamilyIPV6 (or vice versa) fails immediately; so does adding to a set destroyed out-of-band (ipset destroy X) or by a concurrent agent between create and add.","commonSituations":"Management distributes a route group mixing IPv4 and IPv6 ranges into one rule; a second netbird instance (or manual ipset flush/destroy) races the first; host with IPv6 disabled receiving v6 routes (the -v6 suffix naming in ipsetName exists precisely to avoid cross-family collisions).","solutions":["Split route groups so each rule's prefixes share one address family (per-family routing rules)","Ensure only one netbird daemon manages the host; stop duplicates before retrying","Check 'ipset list <name>' to see whether the set exists and with which family (header 'Family: inet/inet6')","Reconnect/re-apply the network map so the refcounter recreates the set atomically (down/up)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// reject mixed-family prefix lists before handing them to the router\nfunc prefixesMatchFamily(prefixes []netip.Prefix, wantV6 bool) bool {\n\tfor _, p := range prefixes {\n\t\tif p.Addr().Is6() != wantV6 || p.Addr().Is4In6() {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Split routing rules per address family on the management side","Normalize prefixes with Unmap() and Addr().Is4In6 checks before building ipset entries","Never manipulate nb-* ipsets manually while the agent runs"],"tags":["iptables","ipset","ipv6","linux","netbird"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}