netbirdio/netbird · error
create v6 acl manager: %w
Error message
create v6 acl manager: %w
What it means
Raised while building the IPv6 half of the iptables firewall Manager: Manager.Create sees wgIface.Address().HasIPv6() and calls createIPv6Components, which constructs the ip6tables client, the v6 router, and finally the v6 aclManager via newAclManager(ip6Client, wgIface). The wrap carries whatever that constructor returns. In the current tree newAclManager only fills a struct (acl_linux.go:50-59) and always returns nil, so this specific wrap is defensive and effectively unreachable in stock code; upstream it surfaces as 'create IPv6 firewall: create v6 acl manager: ...'.
Source
Thrown at client/firewall/iptables/manager_linux.go:97
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 nil
}
func (m *Manager) hasIPv6() bool {
return m.ipv6Client != nil
}
func (m *Manager) Init(stateManager *statemanager.Manager) error {
state := &ShutdownState{
InterfaceState: &InterfaceState{
NameStr: m.wgIface.Name(),
WGAddress: m.wgIface.Address(),
MTU: m.router.mtu,
},
}
stateManager.RegisterState(state)View on GitHub (pinned to 93e97f4bf1)
Solutions
- Read the wrapped error for the real cause; the %w chain names the exact failing constructor
- Verify ip6tables works as root: ip6tables -L on the same host
- If IPv6 is not needed, run the peer with a v4-only WgAddr so Create skips createIPv6Components entirely
- Compare your newAclManager against upstream if the tree is modified
Defensive patterns
Strategy: try-catch
Validate before calling
// v6 components are only built when the interface has a v6 address
if wgIface.Address().HasIPv6() {
if _, err := exec.LookPath("ip6tables"); err != nil {
log.Warnf("v6 address present but ip6tables missing: %v", err)
}
} Try / catch
mgr, err := iptables.Create(wgIface, mtu)
if err != nil {
var v6Err *someConstructorError // inspect errors.Unwrap chain for 'create v6 acl manager'
if errors.As(err, &v6Err) || strings.Contains(err.Error(), "create IPv6 firewall") {
// fall back to a v4-only interface address and retry Create
}
return err
} Prevention
- Ensure iptables and ip6tables are both installed before the daemon starts
- Keep the overlay address family consistent with the rules you intend to program
- Run the agent as root so constructor-time netfilter probes succeed
When it happens
Trigger: Calling firewall.Create(wgIface, mtu) on a Linux host where the overlay interface address contains an IPv6 part, and newAclManager returning a non-nil error (only possible in forks/older versions where the constructor performs fallible work such as probing ipset support).
Common situations: Custom builds or forks that added validation to newAclManager; version drift between the manager and a vendored iptables package; ShutdownState.Cleanup at next startup (state_linux.go:76) also re-enters this path and logs the failure.
Related errors
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/c927c79db533e1e4.
Report an issue: GitHub.