cilium/cilium · error

unable to rename %s chain to %s: %s (%w)

Error message

unable to rename %s chain to %s: %s (%w)

What it means

Thrown when `iptables -t <table> -E <old> <new>` fails while renaming a Cilium custom chain (part of Cilium's atomic rule-installation flow where new chains are built under temporary names and renamed into place). The wrapped output/error indicates why the rename was rejected.

Source

Thrown at pkg/datapath/iptables/custom_chain.go:159

			return err
		}
	}

	return nil
}

func (c *customChain) doRename(prog runnable, newName string) error {
	if exists, err := c.exists(prog); err != nil {
		return err
	} else if !exists {
		return nil
	}

	args := []string{"-t", c.table, "-E", c.name, newName}

	output, err := prog.runProgOutput(args)
	if err != nil {
		return fmt.Errorf("unable to rename %s chain to %s: %s (%w)", c.name, newName, string(output), err)
	}

	return nil
}

func (c *customChain) rename(ipv4, ipv6 bool, name string, ip4tables, ip6tables iptablesInterface) error {
	if ipv4 {
		if err := c.doRename(ip4tables, name); err != nil {
			return err
		}
	}
	if ipv6 && c.ipv6 {
		if err := c.doRename(ip6tables, name); err != nil {
			return nil
		}
	}

	return nil

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Check for and remove leftover chains with the target name (`iptables -t <table> -S | grep <name>`), then restart Cilium.
  2. Ensure NET_ADMIN capability and a functioning iptables binary.
  3. If a prior add failed, fix the root cause (see chain add errors) so rename operates on an existing chain.
  4. Inspect the wrapped output for the precise iptables error message.
Defensive patterns

Strategy: try-catch

Validate before calling

// detect a stale destination chain before renaming
out, _ := exec.Command("iptables", "-t", table, "-S", newName).CombinedOutput()
if len(out) > 0 {
	exec.Command("iptables", "-t", table, "-F", newName).Run()
	exec.Command("iptables", "-t", table, "-X", newName).Run()
}

Try / catch

if err := chain.rename(ipv4, ipv6, newName, ip4, ip6); err != nil {
	if strings.Contains(err.Error(), "already exists") {
		// clean stale chain and retry once
		cleanupStaleChain(table, newName)
		return chain.rename(ipv4, ipv6, newName, ip4, ip6)
	}
	return err
}

Prevention

When it happens

Trigger: rename -> doRename when the -E command fails: target name already in use, source chain missing (e.g. prior doAdd failed or was cleaned up), missing privileges, or missing iptables binary.

Common situations: A previous partial Cilium run left a stale chain with the destination name; another iptables manager (Docker/kube-proxy scripts) claiming the same chain name; unprivileged container; legacy/nftables backend mismatch.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/efb00854c6fd6322. Report an issue: GitHub.