netbirdio/netbird · error
allow netbird v6 interface traffic: %w
Error message
allow netbird v6 interface traffic: %w
What it means
IPv6 counterpart of the blanket overlay accept in AllowNetbird: with hasIPv6() true it appends an ACCEPT for net.IPv6zero through aclMgr6.AddPeerFiltering. Failure means the v6 accept rule could not be installed, so v6 overlay traffic may be dropped by the kernel chain while userspace filtering believes it is pre-allowed. Accumulated alongside the v4 result and returned as a multierror.
Source
Thrown at client/firewall/iptables/manager_linux.go:385
if err := stateManager.DeleteState(&ShutdownState{}); err != nil {
merr = multierror.Append(merr, fmt.Errorf("delete state: %w", err))
}
}
return nberrors.FormatErrorOrNil(merr)
}
// AllowNetbird allows netbird interface traffic.
// This is called when USPFilter wraps the native firewall, adding blanket accept
// rules so that packet filtering is handled in userspace instead of by netfilter.
func (m *Manager) AllowNetbird() error {
var merr *multierror.Error
if _, err := m.AddPeerFiltering(nil, net.IP{0, 0, 0, 0}, firewall.ProtocolALL, nil, nil, firewall.ActionAccept, ""); err != nil {
merr = multierror.Append(merr, fmt.Errorf("allow netbird v4 interface traffic: %w", err))
}
if m.hasIPv6() {
if _, err := m.AddPeerFiltering(nil, net.IPv6zero, firewall.ProtocolALL, nil, nil, firewall.ActionAccept, ""); err != nil {
merr = multierror.Append(merr, fmt.Errorf("allow netbird v6 interface traffic: %w", err))
}
}
if err := firewalld.TrustInterface(m.wgIface.Name()); err != nil {
log.Warnf("failed to trust interface in firewalld: %v", err)
}
return nberrors.FormatErrorOrNil(merr)
}
// Flush doesn't need to be implemented for this manager
func (m *Manager) Flush() error { return nil }
// SetLogLevel sets the log level for the firewall manager
func (m *Manager) SetLogLevel(log.Level) {
// not supported
}
View on GitHub (pinned to 93e97f4bf1)
Solutions
- Restart the agent so Init rebuilds v6 chains and AllowNetbird retries
- Verify with ip6tables -S NETBIRD-ACL-INPUT as root
- Identify and scope the external tool that flushes v6 chains
Defensive patterns
Strategy: try-catch
Validate before calling
if hasV6 := wgIface.Address().HasIPv6(); hasV6 {
if _, err := exec.Command("ip6tables", "-S", "NETBIRD-ACL-INPUT").Output(); err != nil {
log.Warnf("v6 ACL chain missing; v6 pre-accept may fail")
}
} Try / catch
if err := fm.AllowNetbird(); err != nil {
var merr *multierror.Error
if errors.As(err, &merr) {
for _, e := range merr.Errors {
if strings.Contains(e.Error(), "v6 interface traffic") {
log.Errorf("v6 overlay traffic may be dropped: %v", e)
}
}
}
} Prevention
- Ensure v6 chains exist before userspace filtering wraps the manager
- Restart the agent to rebuild chains and retry the pre-accept rules
- On v6-capable overlays, monitor ip6tables chain presence after external firewall jobs
When it happens
Trigger: AllowNetbird on a v6-capable manager where the ip6tables append fails - v6 ACL chain missing after external flush or ip6tables erroring mid-operation.
Common situations: Firewalld/ip6tables-restore rewrites during agent startup; v6 chains removed between Init and AllowNetbird; flaky ip6tables on older kernels.
Related errors
- add peer filtering for %s: %w
- reset v6 acl manager: %w
- allow netbird v4 interface traffic: %w
- add IP to ipset: %w
- failed to check rule: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/accb878961450c67.
Report an issue: GitHub.