netbirdio/netbird · warning
reset acl manager: %w
Error message
reset acl manager: %w
What it means
During Manager.Close, the v4 aclMgr.Reset() failed - removing NETBIRD-ACL-INPUT, its jump rule from INPUT, optional entries, and v4 ipsets. It runs after the v6 resets and is likewise accumulated, never aborting the remaining v4 router reset or firewalld untrust. Blocked DeleteState keeps the shutdown state persisted for retry.
Source
Thrown at client/firewall/iptables/manager_linux.go:353
defer m.mutex.Unlock()
var merr *multierror.Error
if err := m.cleanupNoTrackChain(); err != nil {
merr = multierror.Append(merr, fmt.Errorf("cleanup notrack chain: %w", err))
}
if m.hasIPv6() {
if err := m.aclMgr6.Reset(); err != nil {
merr = multierror.Append(merr, fmt.Errorf("reset v6 acl manager: %w", err))
}
if err := m.router6.Reset(); err != nil {
merr = multierror.Append(merr, fmt.Errorf("reset v6 router: %w", err))
}
}
if err := m.aclMgr.Reset(); err != nil {
merr = multierror.Append(merr, fmt.Errorf("reset acl manager: %w", err))
}
if err := m.router.Reset(); err != nil {
merr = multierror.Append(merr, fmt.Errorf("reset router: %w", err))
}
// Appending to merr intentionally blocks DeleteState below so ShutdownState
// stays persisted and the crash-recovery path retries firewalld cleanup.
if err := firewalld.UntrustInterface(m.wgIface.Name()); err != nil {
merr = multierror.Append(merr, err)
}
// attempt to delete state only if all other operations succeeded
if merr == nil {
if err := stateManager.DeleteState(&ShutdownState{}); err != nil {
merr = multierror.Append(merr, fmt.Errorf("delete state: %w", err))
}
}
View on GitHub (pinned to 93e97f4bf1)
Solutions
- Re-run Close, or restart and stop the agent so next-start Cleanup retries
- Confirm cleanliness with iptables -S INPUT | grep NETBIRD and ipset list
- Remove leftover NETBIRD-ACL-INPUT chain by hand if immediate cleanup is required
Defensive patterns
Strategy: retry
Try / catch
if err := mgr.Close(stateManager); err != nil {
var merr *multierror.Error
if errors.As(err, &merr) {
for _, e := range merr.Errors {
log.Debugf("firewall teardown partial: %v", e)
}
}
// ShutdownState persists; next start re-runs Cleanup
} Prevention
- Expect teardown of already-flushed chains to error; verify final state with iptables -S instead
- Keep the state directory healthy so recovery can find the persisted rules
- Avoid double-calling Close from different goroutines (it is mutex-guarded but wasteful)
When it happens
Trigger: Close where a v4 iptables or ipset delete errors: chain INPUT's jump already removed, ipset still referenced, permissions dropped before teardown.
Common situations: Prior crash-recovery cleanup already removed v4 chains; concurrent iptables rewrite; agent stopped without root.
Related errors
- reset v6 acl manager: %w
- add IP to ipset: %w
- failed to check rule: %w
- rule already exists
- failed to delete rule: %s, %v: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/b504a0cbcc11da4e.
Report an issue: GitHub.