{"record":{"id":"7779e021b9fe1726","repo":"cilium/cilium","slug":"s-is-a-file-which-is-not-a-directory-7779e0","errorCode":null,"errorMessage":"%s is a file which is not a directory","messagePattern":"(.+?) is a file which is not a directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/cgroups/cgroups_linux.go","lineNumber":28,"sourceCode":"\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/cilium/cilium/pkg/mountinfo\"\n)\n\n// mountCgroup mounts the Cgroup v2 filesystem into the desired cgroupRoot directory.\nfunc mountCgroup() error {\n\tcgroupRootStat, err := os.Stat(cgroupRoot)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\tif err := os.MkdirAll(cgroupRoot, 0755); err != nil {\n\t\t\t\treturn fmt.Errorf(\"Unable to create cgroup mount directory: %w\", err)\n\t\t\t}\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"Failed to stat the mount path %s: %w\", cgroupRoot, err)\n\t\t}\n\t} else if !cgroupRootStat.IsDir() {\n\t\treturn fmt.Errorf(\"%s is a file which is not a directory\", cgroupRoot)\n\t}\n\n\tif err := unix.Mount(\"none\", cgroupRoot, \"cgroup2\", 0, \"\"); err != nil {\n\t\treturn fmt.Errorf(\"failed to mount %s: %w\", cgroupRoot, err)\n\t}\n\n\treturn nil\n}\n\n// checkOrMountCustomLocation tries to check or mount the cgroup filesystem in the\n// given path.\nfunc cgrpCheckOrMountLocation(cgroupRoot string) error {\n\tsetCgroupRoot(cgroupRoot)\n\n\t// Check whether the custom location has a mount.\n\tmounted, cgroupInstance, err := mountinfo.IsMountFS(mountinfo.FilesystemTypeCgroup2, cgroupRoot)\n\tif err != nil {\n\t\treturn err","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/cgroups/cgroups_linux.go#L10-L46","documentation":"If `os.Stat(cgroupRoot)` succeeds but shows the path is a regular file rather than a directory, cilium cannot mount cgroup2 there and fails with this error.","triggerScenarios":"`cgrpCheckOrMountLocation` -> `mountCgroup` when a file already exists at the configured cgroup-root path (e.g. a stale bind-mounted file, a leftover from a bad provisioner, or someone created the path with `touch`).","commonSituations":"Kubernetes hostPath volumes created with `type: File`; leftover artifacts after failed upgrades; manual misconfiguration of --cgroup-root.","solutions":["Remove or rename the file: `rm /run/cilium/cgroupv2` (verify it's not needed), then let cilium recreate it","Fix the Kubernetes volume `type` to `DirectoryOrCreate`","Point `--cgroup-root` at a proper empty directory"],"exampleFix":"# before\nls -la /run/cilium/cgroupv2   # -rw-r--r-- file\n# after\nrm /run/cilium/cgroupv2\nmkdir -p /run/cilium/cgroupv2","handlingStrategy":"validation","validationCode":"const cgroupRoot = \"/run/cilium/cgroupv2\"\nif fi, err := os.Stat(cgroupRoot); err == nil && !fi.IsDir() {\n    return fmt.Errorf(\"%s exists but is not a directory; remove it\", cgroupRoot)\n}","typeGuard":null,"tryCatchPattern":"if err := cgroups.Init(cgroupRoot); err != nil {\n    if strings.Contains(err.Error(), \"is a file which is not a directory\") {\n        os.Remove(cgroupRoot) // careful: only if stale\n        return cgroups.Init(cgroupRoot)\n    }\n    return err\n}","preventionTips":["Use hostPath type DirectoryOrCreate, not File","After upgrades, verify the cgroup-root path with `ls -la`","Never create the path with touch/cp; only mkdir"],"tags":["cgroup","filesystem","configuration"],"backgroundTag":"path-not-a-directory","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}