netbirdio/netbird · error

init iptables: %w

Error message

init iptables: %w

What it means

Manager creation failed at iptables.NewWithProtocol(ProtocolIPv4): go-iptables locates an iptables binary (iptables or iptables-nft depending on version), runs `iptables --version`, and parses the version; failure means no usable binary in PATH, an unreadable/old binary (below the supported version), or an exec error. This aborts iptables firewall manager construction entirely, so the agent either falls back to another firewall backend or fails to start.

Source

Thrown at client/firewall/iptables/manager_linux.go:52

	rawSupported bool

	// IPv6 counterparts, nil when no v6 overlay
	ipv6Client *iptables.IPTables
	aclMgr6    *aclManager
	router6    *router
}

// iFaceMapper defines subset methods of interface required for manager
type iFaceMapper interface {
	Name() string
	Address() wgaddr.Address
}

// Create iptables firewall manager
func Create(wgIface iFaceMapper, mtu uint16) (*Manager, error) {
	iptablesClient, err := iptables.NewWithProtocol(iptables.ProtocolIPv4)
	if err != nil {
		return nil, fmt.Errorf("init iptables: %w", err)
	}

	m := &Manager{
		wgIface:    wgIface,
		ipv4Client: iptablesClient,
	}

	m.router, err = newRouter(iptablesClient, wgIface, mtu)
	if err != nil {
		return nil, fmt.Errorf("create router: %w", err)
	}

	m.aclMgr, err = newAclManager(iptablesClient, wgIface)
	if err != nil {
		return nil, fmt.Errorf("create acl manager: %w", err)
	}

	if wgIface.Address().HasIPv6() {

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Install iptables in the target image/host (e.g. `apt-get install -y iptables` or `apk add iptables iptables-nft`).
  2. Ensure the service unit PATH includes /usr/sbin and /sbin, or use an absolute path via go-iptables' binary selection if wrapped.
  3. Verify manually: `iptables --version` as the same user/env the daemon uses.
  4. If the host is nft-only, prefer the nftables firewall manager instead of installing legacy iptables.

Example fix

# before: container image with no iptables
FROM scratch ...

# after
RUN apk add --no-cache iptables ip6tables ipset
# or for debian-based images:
RUN apt-get update && apt-get install -y iptables ipset
Defensive patterns

Strategy: validation

Validate before calling

func verifyIptablesBinaries() error {
    bins := []string{"iptables"}
    for _, b := range bins {
        p, err := exec.LookPath(b)
        if err != nil {
            return fmt.Errorf("%s not found in PATH %q: %w", b, os.Getenv("PATH"), err)
        }
        out, err := exec.Command(p, "--version").Output()
        if err != nil {
            return fmt.Errorf("%s --version failed: %w", p, err)
        }
        _ = out // presence and executability are what matter pre-flight
    }
    return nil
}

// call before iptables.Create(...)

Try / catch

if _, err := iptablesMgr.Create(wgIface, mtu); err != nil {
    if strings.Contains(err.Error(), "init iptables") {
        // environment defect: no usable binary; install iptables or use the nftables manager
        log.Fatalf("iptables unavailable: %v; install iptables or switch firewall backend", err)
    }
}

Prevention

When it happens

Trigger: Running the agent in a minimal/distroless container without iptables installed; systemd/service environments whose PATH omits /usr/sbin where iptables lives; an iptables wrapper or broken symlink first in PATH; an extremely old iptables (<1.4.11).

Common situations: Scratch/distroless Docker images; macOS/Windows dev builds of Linux binaries tested in odd sandboxes; PATH stripped by su/sudo -E invocations; nft-only hosts where iptables-nft is absent but legacy iptables was removed.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/3353d86b9ed52d19. Report an issue: GitHub.