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
- Set values.cni.istioOwnedCNIConfigFilename (or REPAIR_CNI_NETDIR/related values) to a filename that sorts before all others, e.g. '00-istio-cni.conf'.
- 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.
- Remove or rename the file that is outranking the Istio-owned config if it is stale.
- 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
- Name the Istio-owned config 00-istio-cni.conf so nothing can outrank it lexicographically.
- Check which filenames your platform CNI writes before choosing the Istio-owned name.
- Never delete the Istio-owned file while the feature is enabled; alert on its absence.
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
- istio-cni plugin not found in Istio CNI config at %s
- failed to parse ambient enablement selector: %v
- failed to instantiate ambient enablement selector: %v
- failed to create ambient nodeagent service: %v
- failed to parse ambient enablement selector: %v
AI-assisted analysis of istio/istio@8dc789c5cf (2026-08-15).
Data as JSON: /api/errors/86fdeed81c2e3497.
Report an issue: GitHub.