hashicorp/nomad · error
failed to detect CNI conf files: %v
Error message
failed to detect CNI conf files: %v
What it means
The CNI fingerprinter calls libcni.ConfFiles on the configured CNI config directory (client config cni_config_dir) to enumerate .conf/.conflist/.json network definitions. This error means libcni.ConfFiles itself failed - distinct from the directory not existing (which is handled and just skips detection). ConfFiles fails when the path exists but is not a directory, or when reading it errors (permissions, I/O).
Source
Thrown at client/fingerprint/cni.go:38
logger hclog.Logger
}
func NewCNIFingerprint(logger hclog.Logger) Fingerprint {
return &CNIFingerprint{logger: logger}
}
func (f *CNIFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error {
confDir := req.Config.CNIConfigDir
networks := map[string]struct{}{}
if _, err := os.Stat(confDir); os.IsNotExist(err) {
f.logger.Debug("CNI config dir is not set or does not exist, skipping", "cni_config_dir", confDir)
resp.Detected = false
return nil
}
files, err := libcni.ConfFiles(confDir, []string{".conf", ".conflist", ".json"})
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)
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Verify cni_config_dir points to a real directory: 'ls -ld /opt/cni/config' (or your configured path).
- Fix ownership/permissions so the Nomad agent user can read it (e.g. chmod/chown the directory).
- Correct the client config if it points at a file; restart the Nomad client after fixing.
- Ensure the path is not a broken or wrong symlink target.
Example fix
HCL
# before
client {
cni_config_dir = "/opt/cni/bin/myconf.conflist" # a file, not a dir
}
# after
client {
cni_config_dir = "/opt/cni/net.d" # existing, readable directory
}
# then: sudo chown nomad:nomad /opt/cni/net.d && sudo systemctl restart nomad Defensive patterns
Strategy: validation
Validate before calling
// caller-side preflight before relying on CNI fingerprint
confDir := cfg.Client.CNIConfigDir
if fi, err := os.Stat(confDir); err != nil {
return fmt.Errorf("CNI config dir %q unreadable: %w", confDir, err)
} else if !fi.IsDir() {
return fmt.Errorf("CNI config dir %q is not a directory", confDir)
}
// also ensure readability: os.ReadDir(confDir) as a dry run Try / catch
if err := fingerprintErr; err != nil {
if strings.Contains(err.Error(), "failed to detect CNI conf files") {
return fmt.Errorf("check cni_config_dir points to an existing, readable DIRECTORY owned by the nomad user: %w", err)
}
return err
} Prevention
- Point cni_config_dir at a directory (e.g. /opt/cni/net.d), never a file, and never the plugins bin dir.
- Ensure the Nomad agent user can read/traverse the directory (chown/chmod after provisioning).
- Include CNI config dir setup in the same provisioning tooling that installs CNI plugins.
- Restart the Nomad client after changing the directory's location or permissions.
When it happens
Trigger: client config cni_config_dir points to a path that exists (os.Stat succeeded) but is a regular file, a symlink to a non-directory, or cannot be read by the Nomad agent user (permission denied); libcni.ConfFiles returns the underlying os error which is wrapped here.
Common situations: cni_config_dir misconfigured to point at a file (e.g. the binary or a conf file itself) instead of a directory; directory owned by root with restrictive permissions while Nomad runs as an unprivileged user; directory removed/replaced with a file after client start.
Related errors
- network namespace already exists but was misconfigured
- no CNI network config found
- plugin not executable
- Permission denied
- missing attributes for client registration
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/775fd3c527c4e649.
Report an issue: GitHub.