netbirdio/netbird · error
init ip6tables: %w
Error message
init ip6tables: %w
What it means
iptables.NewWithProtocol(ProtocolIPv6) failed inside createIPv6Components: go-iptables could not find or execute a usable ip6tables binary (or its nft variant) or could not parse `ip6tables --version`. This runs only when the interface has an IPv6 address, so v4-only hosts never hit it, but any dual-stack host without the v6 binary fails manager creation.
Source
Thrown at client/firewall/iptables/manager_linux.go:82
m.aclMgr, err = newAclManager(iptablesClient, wgIface)
if err != nil {
return nil, fmt.Errorf("create acl manager: %w", err)
}
if wgIface.Address().HasIPv6() {
if err := m.createIPv6Components(wgIface, mtu); err != nil {
return nil, fmt.Errorf("create IPv6 firewall: %w", err)
}
}
return m, nil
}
func (m *Manager) createIPv6Components(wgIface iFaceMapper, mtu uint16) error {
ip6Client, err := iptables.NewWithProtocol(iptables.ProtocolIPv6)
if err != nil {
return fmt.Errorf("init ip6tables: %w", err)
}
m.ipv6Client = ip6Client
m.router6, err = newRouter(ip6Client, wgIface, mtu)
if err != nil {
return fmt.Errorf("create v6 router: %w", err)
}
// Share the same IP forwarding state with the v4 router, since
// Forwarding refcounter is per-family but shared between v4 and v6 routers.
m.router6.ipFwdState = m.router.ipFwdState
m.aclMgr6, err = newAclManager(ip6Client, wgIface)
if err != nil {
return fmt.Errorf("create v6 acl manager: %w", err)
}
return nilView on GitHub (pinned to 93e97f4bf1)
Solutions
- Install ip6tables alongside iptables in the image/host (e.g. `apk add ip6tables` or the iptables package's v6 component).
- Fix the service PATH to include /usr/sbin, /sbin.
- Verify with `ip6tables --version` under the daemon's user and environment.
- If v6 is not actually needed, remove the v6 address from the NetBird interface to skip this path entirely.
Example fix
# alpine image RUN apk add --no-cache iptables ip6tables ipset # debian image RUN apt-get update && apt-get install -y iptables ip6tables ipset
Defensive patterns
Strategy: validation
Validate before calling
func verifyIp6tablesBinary() error {
p, err := exec.LookPath("ip6tables")
if err != nil {
return fmt.Errorf("ip6tables not found (required when the interface has an IPv6 address): %w", err)
}
if out, err := exec.Command(p, "--version").CombinedOutput(); err != nil {
return fmt.Errorf("ip6tables --version failed: %s: %w", out, err)
}
return nil
}
// call before iptables.Create() when the overlay is dual-stack Try / catch
if _, err := iptablesMgr.Create(wgIface, mtu); err != nil {
if strings.Contains(err.Error(), "init ip6tables") {
// install the v6 binary or drop the interface's v6 address to skip the v6 path
log.Fatalf("ip6tables unavailable but interface is dual-stack: %v", err)
}
} Prevention
- Package ip6tables with iptables in all agent images (apk: ip6tables; deb: part of iptables).
- Watch service PATH; ip6tables usually lives in /usr/sbin like iptables.
- Decide dual-stack deliberately: if v6 is unused, keep it off the interface so the binary is never required.
- Add a deployment preflight that runs `ip6tables --version` under the daemon's uid.
When it happens
Trigger: Interface has a v6 address but ip6tables is not installed or not in the daemon's PATH; ip6tables exists but is a broken symlink/wrapper; version output unparseable (nonstandard wrapper scripts).
Common situations: Images that install `iptables` but not `ip6tables`; service units with minimal PATH; custom busybox wrappers; nft-only systems missing ip6tables-nft.
Related errors
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/c751cea5853bb778.
Report an issue: GitHub.