istio/istio · error

istio owned CNI config does not exist or is not the highest

Error message

istio owned CNI config does not exist or is not the highest priority. Got %s instead

What it means

checkValidCNIConfig enforces that when the Istio-owned CNI config feature is enabled, the Istio-owned file (values.cni.istioOwnedCNIConfigFilename, e.g. 00-istio-cni.conf) must be the highest-priority (lexicographically first) config in the netdir. The error reports which file currently sorts first instead; a preceding log warning explains the priority mismatch and the mesh-bypass risk.

Source

Thrown at cni/pkg/install/install.go:299

		// if Istio owned CNI config is enabled, the first CNI config file must be the Istio owned CNI config
		if firstCNIConfigFilename != cfg.IstioOwnedCNIConfigFilename {
			// if the default or specified CNI config file doesn't exist or is not the highest priority return
			// an error

			// check the priority of the IstioOwnedCNIConfigFilename compared to the first CNI config file
			// warn if the istio owned CNI config is not the highest priority - this is undefined behavior
			if strings.Compare(firstCNIConfigFilename, cfg.IstioOwnedCNIConfigFilename) <= 0 {
				log.Warnf("Istio owned CNI config %s has lower priority than %s. "+
					" This will lead to undefined behavior and potential bypass of the service mesh.",
					cfg.IstioOwnedCNIConfigFilename, firstCNIConfigFilename)
			}
			if len(cfg.CNIConfName) == 0 {
				// We found the primary CNI config file (or the highest priority config file).
				// Set the filename to the CNIConfName if it isn't set
				cfg.CNIConfName = firstCNIConfigFilename
			}
			return fmt.Errorf("istio owned CNI config does not exist or is not the highest priority. Got %s instead", firstCNIConfigFilename)
		}
		log.Debugf("istio owned CNI config is the highest priority: %s", firstCNIConfigFilename)
	}

	// filepath for the highest priority, valid config
	defaultCNIConfigFilepath := filepath.Join(cfg.MountedCNINetDir, firstCNIConfigFilename)

	// cniConfigFilepath is only set once the CNI config file has been validated or created at least once
	// so even if the CNI config file is valid, it will not be equal to the cniConfigFilepath during the
	// first call of checkValidCNIConfig and we will return an error so the cni config file can be
	// created or rewritten
	if defaultCNIConfigFilepath != cniConfigFilepath {
		log.Debugf("cniConfigFilePath mismatch: expected %s but found %s", defaultCNIConfigFilepath, cniConfigFilepath)
		if len(cfg.CNIConfName) > 0 || !cfg.ChainedCNIPlugin {
			// Install was run with overridden CNI config file so don't error out on preempt check
			// Likely the only use for this is testing the script
			installLog.Warnf("CNI config file %q preempted by %q", cniConfigFilepath, defaultCNIConfigFilepath)
		} else {

View on GitHub (pinned to 8dc789c5cf)

Solutions

  1. Set values.cni.istioOwnedCNIConfigFilename (or REPAIR_CNI_NETDIR/related values) to a filename that sorts before all others, e.g. '00-istio-cni.conf'.
  2. Alternatively disable the Istio-owned config feature (values.cni.ambient or the dedicated flag per your chart version) so Istio chains into the primary CNI's own file.
  3. Remove or rename the file that is outranking the Istio-owned config if it is stale.
  4. Restart the istio-cni-node pod after fixing names so checkValidCNIConfig re-evaluates priority.

Example fix

# before
istioctl install --set values.cni.istioOwnedCNIConfigFilename=10-istio-cni.conf  # '05-cilium.conflist' wins
# after
istioctl install --set values.cni.istioOwnedCNIConfigFilename=00-istio-cni.conf
Defensive patterns

Strategy: validation

Validate before calling

// Before enabling Istio-owned CNI config, assert its filename sorts first in the netdir.
func istioOwnedFileHasPriority(netDir, istioFile string) (bool, string, error) {
	entries, err := os.ReadDir(netDir)
	if err != nil {
		return false, "", err
	}
	first := ""
	for _, e := range entries {
		if e.IsDir() {
			continue
		}
		if first == "" || e.Name() < first {
			first = e.Name()
		}
	}
	return first == istioFile, first, nil
}

Try / catch

if err := checkValidCNIConfig(ctx, cfg, path); err != nil {
    if strings.Contains(err.Error(), "istio owned CNI config does not exist or is not the highest priority") {
        // deterministic: fix the filename ordering, then retry — do not loop on the same values
        return fmt.Errorf("rename %s so it sorts before all other CNI configs (e.g. 00-istio-cni.conf)", cfg.IstioOwnedCNIConfigFilename)
    }
    return err
}

Prevention

When it happens

Trigger: useIstioOwnedCNIConfig(cfg) is true and firstCNIConfigFilename != cfg.IstioOwnedCNIConfigFilename — another CNI config file (e.g., 05-cilium.conflist vs 10-istio-cni.conf naming) sorts before the Istio-owned filename, or the Istio-owned file does not exist yet in the directory.

Common situations: Platform CNIs (Cilium on EKS/GKE, OVN) install configs prefixed such that they outrank the Istio-owned name; the Istio-owned file was deleted by another agent; the feature value values.cni.istioOwnedCNIConfigFilename was customized to a name that does not sort first; fresh nodes where ordering is nondeterministic.

Related errors


AI-assisted analysis of istio/istio@8dc789c5cf (2026-08-15). Data as JSON: /api/errors/86fdeed81c2e3497. Report an issue: GitHub.