netbirdio/netbird · warning
remove v4 NAT rule: %w
Error message
remove v4 NAT rule: %w
What it means
Best-effort teardown error: RemoveNatRule failed to delete the v4 half of a NAT pair via router.RemoveNatRule, and it was accumulated into a multierror (the v6 half is still attempted afterwards). Most commonly the underlying iptables Delete fails because the rule is already gone - chains were flushed externally or a previous Close removed them.
Source
Thrown at client/firewall/iptables/manager_linux.go:309
return nil
}
func (m *Manager) RemoveNatRule(pair firewall.RouterPair) error {
m.mutex.Lock()
defer m.mutex.Unlock()
if pair.Destination.IsPrefix() && pair.Destination.Prefix.Addr().Is6() {
if !m.hasIPv6() {
return nil
}
return m.router6.RemoveNatRule(pair)
}
var merr *multierror.Error
if err := m.router.RemoveNatRule(pair); err != nil {
merr = multierror.Append(merr, fmt.Errorf("remove v4 NAT rule: %w", err))
}
if m.hasIPv6() && pair.Dynamic {
v6Pair := firewall.ToV6NatPair(pair)
if err := m.router6.RemoveNatRule(v6Pair); err != nil {
merr = multierror.Append(merr, fmt.Errorf("remove v6 NAT rule: %w", err))
}
}
return nberrors.FormatErrorOrNil(merr)
}
func (m *Manager) SetLegacyManagement(isLegacy bool) error {
if err := firewall.SetLegacyManagement(m.router, isLegacy); err != nil {
return err
}
if m.hasIPv6() {
return firewall.SetLegacyManagement(m.router6, isLegacy)View on GitHub (pinned to 93e97f4bf1)
Solutions
- Treat as idempotent cleanup: re-run RemoveNatRule or the full Close to converge
- Inspect with iptables-save -t nat | grep NETBIRD to confirm no leftovers remain
- If errors persist across restarts, capture the wrapped ip6tables/iptables message from the daemon log and address that layer
Defensive patterns
Strategy: retry
Try / catch
if err := mgr.RemoveNatRule(pair); err != nil {
var merr *multierror.Error
if errors.As(err, &merr) {
for _, e := range merr.Errors {
log.Debugf("nat teardown partial: %v", e) // usually 'already gone'
}
return nil // treat idempotent-teardown noise as success
}
return err
} Prevention
- Treat NAT teardown errors as retryable: re-invoke removal or rely on Close
- Inspect *multierror.Error to separate v4/v6 halves when diagnosing
- Avoid concurrent external iptables rewrites during agent shutdown
When it happens
Trigger: RemoveNatRule(pair) on a v4-destination pair when the NETBIRD nat chains or the specific rule no longer exist, or the iptables Delete call otherwise errors; result is a *multierror.Error containing 'remove v4 NAT rule: ...'.
Common situations: Agent shutdown racing an external firewall rewrite; double teardown (Close called after a crash-recovery cleanup already removed rules); unprivileged close.
Related errors
- remove v6 NAT rule: %w
- add NAT rule: %w
- add v6 NAT rule: %w
- cleanup notrack chain: %w
- reset v6 acl manager: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/99be3f199386bbf3.
Report an issue: GitHub.