netbirdio/netbird · error
apply network -d: %w
Error message
apply network -d: %w
What it means
Destination-side twin of the source error in addNatRule(): applyNetwork("-d", pair.Destination, nil) fails while creating/refcounting an ipset for a destination network set. With plain prefixes this path cannot error, so seeing this message always implies a set-based destination route and an ipset subsystem failure, wrapped as 'apply network -d'.
Source
Thrown at client/firewall/iptables/router_linux.go:693
markValue = nbnet.PreroutingFwmarkMasqueradeReturn
}
rule := []string{"-i", r.wgIface.Name()}
if pair.Inverse {
rule = []string{"!", "-i", r.wgIface.Name()}
}
rule = append(rule,
"-m", "conntrack",
"--ctstate", "NEW",
)
sourceExp, err := r.applyNetwork("-s", pair.Source, nil)
if err != nil {
return fmt.Errorf("apply network -s: %w", err)
}
destExp, err := r.applyNetwork("-d", pair.Destination, nil)
if err != nil {
return fmt.Errorf("apply network -d: %w", err)
}
rule = append(rule, sourceExp...)
rule = append(rule, destExp...)
rule = append(rule,
"-j", "MARK", "--set-mark", fmt.Sprintf("%#x", markValue),
)
// Ensure nat rules come first, so the mark can be overwritten.
// Currently overwritten by the dst-type LOCAL rules for redirected traffic.
if err := r.iptablesClient.Insert(tableMangle, chainRTPRE, 1, rule...); err != nil {
// TODO: rollback ipset counter
return fmt.Errorf("error while adding marking rule for %s: %v", pair.Destination, err)
}
r.rules[ruleKey] = rule
r.updateState()View on GitHub (pinned to 93e97f4bf1)
Solutions
- Confirm the failing side is the destination set from the log context, then `modprobe ip_set ip_set_hash_net`
- Test manually: `sudo ipset create test hash:net` (and destroy it after)
- Grant CAP_NET_ADMIN / relax seccomp for the agent container so netlink ipset calls work
- Check the set name length in the preceding 'create or get ipset' log line; report over-length names as a management/agent bug
- Retry the route application once modules and permissions are fixed
Example fix
// before: destination and source failures are indistinguishable in ops output
destExp, err := r.applyNetwork("-d", pair.Destination, nil)
if err != nil {
return fmt.Errorf("apply network -d: %w", err)
}
// after: carry the set name into the error for direct diagnosis
destExp, err := r.applyNetwork("-d", pair.Destination, nil)
if err != nil {
if pair.Destination.IsSet() {
return fmt.Errorf("apply destination set %s: %w", pair.Destination.Set.HashedName(), err)
}
return fmt.Errorf("apply network -d: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
func setApplicable(net firewall.Network) error {
if !net.IsSet() {
return nil
}
if _, err := os.Stat("/proc/net/ip_set"); err != nil {
return fmt.Errorf("ipset unavailable for set-based networks: %w", err)
}
return nil
} Try / catch
Same as the source variant: wrap the pair add, distinguish set failures (ipset subsystem) from prefix failures (cannot happen), and requeue the route for the next reconciliation cycle.
Prevention
- Prefer prefix-based destinations when the host kernel lacks ipset
- Smoke-test `ipset create` in host/container bring-up
- Alert on 'apply network -d' lines; they always indicate set-based routing issues
When it happens
Trigger: pair.Destination.IsSet() true and ipsetCounter.Increment failing: ipset modules missing, CAP_NET_ADMIN absent, hashed set name too long for the kernel, or concurrent set creation racing (duplicate-create netlink error not treated as benign). Sources with a plain prefix succeed, isolating the failure to destination sets.
Common situations: Management applies routes whose destination is a network set (e.g. 'all peers' groups) to hosts without ipset support; hardened containers with seccomp blocking NETLINK_NETFILTER; older kernels with stricter ipset name/type validation; one-off breakage after ipset packages were updated on the host.
Related errors
- apply network -s: %w
- error while adding marking rule for %s: %v
- add IP to ipset: %w
- create set %s: %w
- add element to set %s: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/dadc74c6611ef579.
Report an issue: GitHub.