cilium/cilium · error

invalid CNI chaining mode: %s

Error message

invalid CNI chaining mode: %s

What it means

renderCNIConf resolves the CNI chaining mode to a built-in configuration template via cniConfigs[strings.ToLower(c.config.CNIChainingMode)] and, when using chaining or custom templates, checks that some configuration was produced. If cniConfig is empty the chaining mode is not a known value, so Cilium refuses to generate a CNI config it cannot honor.

Source

Thrown at daemon/cmd/cni/config.go:388

// in to an existing CNI network.
func (c *cniConfigManager) renderCNIConf() (cniConfig []byte, err error) {
	if c.config.CNIChainingTarget != "" {
		pluginConfig := c.renderCNITemplate(chainedCNIEntry)
		cniConfig, err = c.mergeExistingCNIConfig(pluginConfig)
		if err != nil {
			return nil, err
		}
	} else {
		c.logger.Info(
			"Generating CNI configuration file with mode",
			logfields.Mode, c.config.CNIChainingMode,
		)
		tmpl := cniConfigs[strings.ToLower(c.config.CNIChainingMode)]
		cniConfig = []byte(c.renderCNITemplate(tmpl))
	}

	if len(cniConfig) == 0 {
		return nil, fmt.Errorf("invalid CNI chaining mode: %s", c.config.CNIChainingMode)
	}

	return cniConfig, nil
}

// mergeExistingCNIConfig looks for an existing cni configuration
// and modifies it to include Cilium. If no configuration is found, it
// fails.
//
// pluginConfig is the raw json to insert in the plugin chain.
//
// This was originally added to interact solely with aws-cni, see
// PR #18522 for details.
func (c *cniConfigManager) mergeExistingCNIConfig(pluginConfig []byte) ([]byte, error) {
	contents, err := c.findCNINetwork(c.config.CNIChainingTarget)
	if err != nil {
		return nil, fmt.Errorf("could not find existing CNI config for chaining: %w", err)
	}

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Set --cni-chaining-mode to a supported value (e.g. none, aws-cni, azure, gke, portmap, flannel) and redeploy the agent.
  2. Check Helm values: cilium cni.chainingMode must match a supported mode exactly; fix typos.
  3. If upgrading, verify the chaining mode still exists in the target Cilium version's cniConfigs map and migrate if removed.
  4. Confirm the agent's ConfigMap actually carries the corrected value (kubectl -n kube-system get cm cilium-config).

Example fix

// before (Helm values)
cni:
  chainingMode: calici
// after
cni:
  chainingMode: portmap
Defensive patterns

Strategy: validation

Validate before calling

var validChainingModes = map[string]bool{
  "none": true, "aws-cni": true, "azure": true, "gke": true,
  "portmap": true, "flannel": true, "generic-veth": true,
}
mode := strings.ToLower(chainingMode)
if !validChainingModes[mode] {
    return fmt.Errorf("unsupported cni-chaining-mode %q", chainingMode)
}

Try / catch

conf, err := manager.renderCNIConf()
if err != nil {
    if strings.HasPrefix(err.Error(), "invalid CNI chaining mode") {
        // fail fast at deploy time: reject bad Helm values before rolling pods
    }
    return err
}

Prevention

When it happens

Trigger: --cni-chaining-mode is set to a value with no entry in the cniConfigs map (and no custom template rendered), e.g. a typo like `flanel` or `calici`, or an empty string when chaining is expected.

Common situations: Typos in Helm values (cni.chainingMode), upgrading Cilium after a chaining mode was renamed/removed, passing the mode with wrong casing to a code path that does not normalize it, enabling chaining without setting the mode at all.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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