{"record":{"id":"88a99f6aedf22f9d","repo":"ahmetb/kubectx","slug":"failed-to-open-file-q-w","errorCode":null,"errorMessage":"failed to open file %q: %w","messagePattern":"failed to open file %q: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/kubeconfig/kubeconfigloader.go","lineNumber":52,"sourceCode":"\tpath string\n}\n\nfunc (kf *kubeconfigFile) Path() string { return kf.path }\n\nfunc (*StandardKubeconfigLoader) Load() ([]ReadWriteResetCloser, error) {\n\tpaths, err := kubeconfigPaths()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot determine kubeconfig path: %w\", err)\n\t}\n\n\tvar files []ReadWriteResetCloser\n\tfor _, p := range paths {\n\t\tf, err := os.OpenFile(p, os.O_RDWR, 0)\n\t\tif err != nil {\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"failed to open file %q: %w\", p, err)\n\t\t}\n\t\tfiles = append(files, &kubeconfigFile{File: f, path: p})\n\t}\n\tif len(files) == 0 {\n\t\treturn nil, fmt.Errorf(\"kubeconfig file not found: %w\",\n\t\t\t&os.PathError{Op: \"open\", Path: paths[0], Err: os.ErrNotExist})\n\t}\n\treturn files, nil\n}\n\nfunc (kf *kubeconfigFile) Reset() error {\n\tif err := kf.Truncate(0); err != nil {\n\t\treturn fmt.Errorf(\"failed to truncate file: %w\", err)\n\t}\n\tif _, err := kf.Seek(0, 0); err != nil {\n\t\treturn fmt.Errorf(\"failed to seek in file: %w\", err)\n\t}\n\treturn nil","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/ahmetb/kubectx/blob/12ad6fb22e8c546ee2b54e7de38aa51c906832f7/internal/kubeconfig/kubeconfigloader.go#L34-L70","documentation":"StandardKubeconfigLoader.Load opens each candidate kubeconfig path with os.OpenFile(..., os.O_RDWR, 0). Paths that don't exist are silently skipped, but any other open error (permissions, is-a-directory, device errors) aborts with this error wrapping the original *os.PathError, which names the failing path in %q and the syscall error in %w.","triggerScenarios":"Calling Load when a path from $KUBECONFIG (or the default ~/.kube/config) exists but cannot be opened for reading and writing — e.g. permission denied (chmod 000 / root-owned file), the path is a directory, or an I/O error occurs.","commonSituations":"KUBECONFIG pointing at a file owned by another user or with 0600 root-only permissions; a stale KUBECONFIG entry that now names a directory; file locked on a network share; running the tool unprivileged against another user's config.","solutions":["Read the wrapped *os.PathError in %w for the exact path and errno, then chmod/chown the file to be writable by the current user","If the path should not be opened, unset it from KUBECONFIG: export KUBECONFIG=\"$HOME/.kube/config\"","If the path is a directory, point KUBECONFIG at actual files only (colon-separated)","Verify the file is not on a read-only/failed mount (ls -l, mount, df)"],"exampleFix":"// before\nexport KUBECONFIG=/root/.kube/config   # permission denied for current user\n// after\nexport KUBECONFIG=$HOME/.kube/config","handlingStrategy":"validation","validationCode":"// Go\nfor _, p := range paths {\n    if fi, err := os.Stat(p); err == nil {\n        if fi.IsDir() { return fmt.Errorf(\"%s is a directory\", p) }\n        if f, err := os.OpenFile(p, os.O_RDWR, 0); err != nil {\n            return fmt.Errorf(\"%s not openable read-write: %v\", p, err)\n        } else { f.Close() }\n    }\n}","typeGuard":"func isPermissionErr(err error) bool {\n    return errors.Is(err, os.ErrPermission)\n}","tryCatchPattern":"files, err := loader.Load()\nvar pe *fs.PathError\nif errors.As(err, &pe) {\n    return fmt.Errorf(\"cannot open %s: %v — check permissions\", pe.Path, pe.Err)\n}","preventionTips":["Keep kubeconfig files at 0600 owned by the running user","Never point KUBECONFIG at directories or root-owned files when running unprivileged","Clean stale entries out of KUBECONFIG periodically","Check mount status (ro flag) for network filesystems"],"tags":["kubeconfig","file-io","permissions","go"],"backgroundTag":"file-open-permission-denied","analyzedSha":"12ad6fb22e8c546ee2b54e7de38aa51c906832f7","analyzedAt":"2026-09-02T12:23:10.107Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}