{"record":{"id":"b4b83af695f5b953","repo":"kubernetes/kops","slug":"error-creating-directories-q-v-b4b83a","errorCode":null,"errorMessage":"error creating directories %q: %v","messagePattern":"error creating directories %q: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/pkg/vfs/fs.go","lineNumber":58,"sourceCode":"\t_ HasHash = &FSPath{}\n)\n\nfunc NewFSPath(location string) *FSPath {\n\treturn &FSPath{location: location}\n}\n\nfunc (p *FSPath) Join(relativePath ...string) Path {\n\targs := []string{p.location}\n\targs = append(args, relativePath...)\n\tjoined := filepath.Join(args...)\n\treturn &FSPath{location: joined}\n}\n\nfunc (p *FSPath) WriteFile(ctx context.Context, data io.ReadSeeker, acl ACL) error {\n\tdir := filepath.Dir(p.location)\n\terr := os.MkdirAll(dir, 0o755)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error creating directories %q: %v\", dir, err)\n\t}\n\n\tf, err := os.CreateTemp(dir, \"tmp\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error creating temp file in %q: %v\", dir, err)\n\t}\n\n\t// Note from here on in we have to close f and delete or rename the temp file\n\ttempfile := f.Name()\n\n\t_, err = io.Copy(f, data)\n\n\tif closeErr := f.Close(); err == nil {\n\t\terr = closeErr\n\t}\n\n\tif err == nil {\n\t\terr = os.Rename(tempfile, p.location)","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/util/pkg/vfs/fs.go#L40-L76","documentation":"FSPath.WriteFile writes files atomically by first creating the target's parent directories with os.MkdirAll. This error wraps any MkdirAll failure — permission denied, read-only filesystem, a non-directory file occupying a path component, etc. The library cannot even create a temp file until the directory exists.","triggerScenarios":"Calling CreateFile/WriteFile on a FSPath whose parent directory cannot be created: permission denied on the parent, a path component exists as a regular file, or the filesystem is read-only/full.","commonSituations":"Running kops as a non-root user against /etc or another root-owned directory, state store local dir pointed at a file rather than a directory, or containers with read-only root filesystems.","solutions":["Fix permissions on the parent path (chown/chmod) or run the process as a user with write access.","Ensure no regular file occupies a directory component of the target path.","Check the filesystem is writable and not full (mount options, disk space).","Point the VFS local path at a directory that exists or can be created."],"exampleFix":"// before\nFSPath{location: \"/etc/kops/config\"} // /etc not writable by current user\n// after\nsudo chown $(whoami) /etc/kops || FSPath{location: \"$HOME/.kops/config\"}","handlingStrategy":"try-catch","validationCode":"dir := filepath.Dir(target)\nif fi, err := os.Stat(dir); err == nil && !fi.IsDir() {\n    return fmt.Errorf(\"%s exists and is not a directory\", dir)\n}\nif err := unix.Access(filepath.Dir(dir), unix.W_OK); err != nil {\n    return fmt.Errorf(\"no write permission on %s: %w\", dir, err)\n}","typeGuard":null,"tryCatchPattern":"if err := p.WriteFile(ctx, data, acl); err != nil && strings.Contains(err.Error(), \"error creating directories\") {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission) {\n        return fmt.Errorf(\"run with write access to %s or pick another path\", filepath.Dir(target))\n    }\n    return err\n}","preventionTips":["Run the process as a user with write access to the state directory.","Pre-create the base state directory at install/deploy time.","Never point local VFS paths at an existing regular file."],"tags":["filesystem","vfs","permissions"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}