hashicorp/nomad · error
failed to load CNI config file %s: %v
Error message
failed to load CNI config file %s: %v
What it means
Same CNI fingerprinter, but for single-network config files (e.g. .conf or .json without the .conflist suffix). libcni.ConfFromFile parses the file into a single CNI config; a read error or invalid single-config JSON aborts the fingerprint with this wrapped error.
Source
Thrown at client/fingerprint/cni.go:55
if err != nil {
return fmt.Errorf("failed to detect CNI conf files: %v", err)
}
for _, confFile := range files {
if strings.HasSuffix(confFile, ".conflist") {
confList, err := libcni.ConfListFromFile(confFile)
if err != nil {
return fmt.Errorf("failed to load CNI config list file %s: %v", confFile, err)
}
if _, ok := networks[confList.Name]; ok {
f.logger.Warn("duplicate CNI config names found, ignoring file", "name", confList.Name, "file", confFile)
continue
}
networks[confList.Name] = struct{}{}
} else {
conf, err := libcni.ConfFromFile(confFile)
if err != nil {
return fmt.Errorf("failed to load CNI config file %s: %v", confFile, err)
}
if _, ok := networks[conf.Network.Name]; ok {
f.logger.Warn("duplicate CNI config names found, ignoring file", "name", conf.Network.Name, "file", confFile)
continue
}
networks[conf.Network.Name] = struct{}{}
}
}
var nodeNetworks structs.Networks
var newNodeNetworks []*structs.NodeNetworkResource
for name := range networks {
mode := fmt.Sprintf("cni/%s", name)
nodeNetworks = append(nodeNetworks, &structs.NetworkResource{
Mode: mode,
})
newNodeNetworks = append(newNodeNetworks, &structs.NodeNetworkResource{View on GitHub (pinned to 482b49bf1a)
Solutions
- Validate the file with jq and ensure it has name, cniVersion, and type fields
- Remove non-CNI files (backups, docs, .tmp) from the CNI conf directory
- Fix file permissions so Nomad can read it
- Reinstall/regenerate the config from your CNI plugin's docs
Example fix
// before (invalid single conf)
{"name":"bridge"}
// after
{"name":"bridge","cniVersion":"0.4.0","type":"bridge"} Defensive patterns
Strategy: validation
Validate before calling
func validateCNIConf(path string) error { b, err := os.ReadFile(path); if err != nil { return err }; var c struct{ Name string `json:"name"`; CNIVersion string `json:"cniVersion"`; Type string `json:"type"` }; if err := json.Unmarshal(b, &c); err != nil { return err }; if c.Name == "" || c.CNIVersion == "" || c.Type == "" { return fmt.Errorf("missing required fields in %s", path) }; return nil } Type guard
func isValidCNIConf(path string) bool { b, err := os.ReadFile(path); if err != nil { return false }; var c struct{ Name, CNIVersion, Type string }; return json.Unmarshal(b, &c) == nil && c.Name != "" && c.CNIVersion != "" && c.Type != "" } Prevention
- Keep only valid CNI configs in the conf dir — no backups or docs
- Add a config-management lint step for CNI configs
- Pin CNI plugin versions and regenerate configs on upgrade
When it happens
Trigger: A non-.conflist file in the CNI conf dir is unreadable, malformed JSON, lacks required fields (name, cniVersion, type), or contains something unexpected like a README.txt or backup copy.
Common situations: Editors leaving .conf.bak or .json.orig files in /opt/cni/net.d; templating tools writing partial configs; missing "type" field in a bridge plugin config; permission changes from config management.
Related errors
- failed to load CNI config list file %s: %v
- failed to initialize table forwarding rules: %v
- invalid ';' character in CNI arg value %q
- network namespace already exists but was misconfigured
- no CNI network config found
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/e2aa622f0c84b085.
Report an issue: GitHub.