{"record":{"id":"8a2019c650eca64f","repo":"hashicorp/nomad","slug":"error-setting-directory-permission-mode-w","errorCode":null,"errorMessage":"error setting directory permission mode: %w","messagePattern":"error setting directory permission mode: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/hostvolumemanager/host_volume_plugin.go","lineNumber":144,"sourceCode":"\n\tparams, err := decodeMkdirParams(req.Parameters)\n\tif err != nil {\n\t\tlog.Error(\"error with parameters\", \"error\", err)\n\t\treturn nil, err\n\t}\n\n\terr = os.MkdirAll(path, params.Mode)\n\tif err != nil {\n\t\tlog.Error(\"error creating directory\", \"error\", err)\n\t\treturn nil, fmt.Errorf(\"error creating directory: %w\", err)\n\t}\n\n\t// os.MkdirAll perms are applied after umask, so the new directory may not\n\t// have the exact permissions requested.\n\terr = os.Chmod(path, params.Mode)\n\tif err != nil {\n\t\tlog.Error(\"error setting directory permission mode\", \"error\", err)\n\t\treturn nil, fmt.Errorf(\"error setting directory permission mode: %w\", err)\n\t}\n\n\tif runtime.GOOS != \"windows\" {\n\t\t// Chown note: A uid or gid of -1 means to not change that value.\n\t\tif err = os.Chown(path, params.Uid, params.Gid); err != nil {\n\t\t\tlog.Error(\"error changing owner/group\", \"error\", err, \"uid\", params.Uid, \"gid\", params.Gid)\n\n\t\t\t// Failing to change ownership is fatal for this plugin. Since we have\n\t\t\t// already created the directory, we should attempt to clean it.\n\t\t\t// Otherwise, the operator must do this manually.\n\t\t\tif err := os.RemoveAll(path); err != nil {\n\t\t\t\tlog.Error(\"failed to remove directory after create failure\",\n\t\t\t\t\t\"error\", err)\n\t\t\t}\n\n\t\t\treturn nil, fmt.Errorf(\"error changing owner/group: %w\", err)\n\t\t}\n\t}","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/hostvolumemanager/host_volume_plugin.go#L126-L162","documentation":"This error wraps a failure of os.Chmod after os.MkdirAll succeeded during the plugin Create operation. Because MkdirAll applies permissions through the process umask, Nomad explicitly chmods the directory to params.Mode; if that chmod fails the directory creation is aborted and this wrapped error is returned. Typical wrapped causes are permission denied (you are not the file owner) or the path being on a filesystem that does not support chmod.","triggerScenarios":"Plugin Create runs: os.MkdirAll succeeds but os.Chmod(path, params.Mode) returns an error — e.g. the new directory was created but its owner differs from the client process user (unusual), the underlying filesystem (some NFS configs, FAT, CIFS) rejects chmod, or the path was concurrently replaced/removed.","commonSituations":"Volume path on an NFS share with root_squash or a filesystem without POSIX permission support; concurrent process removing the directory between mkdir and chmod; umask-related permission surprise making the operator inspect why mode differs (this error is the chmod itself failing, rarer).","solutions":["Inspect the wrapped OS error; if permission denied, ensure the nomad client user owns the newly created directory (check parent directory ownership and mount options).","Check mount type: on NFS/CIFS/FAT mounts that don't honor chmod, pick a path on a local POSIX filesystem or adjust mount options.","Check for external processes (cleanup jobs, antivirus) racing with directory creation and locking/removing the path.","Adjust the requested Mode if it is invalid for the target filesystem."],"exampleFix":"// before: path on CIFS mount that rejects chmod\nPath: \"/mnt/share/vol1\", Mode: 0o750  // chmod fails\n\n// after: use a local POSIX path for host volumes\nPath: \"/opt/nomad/volumes/vol1\", Mode: 0o750","handlingStrategy":"validation","validationCode":"func modeSupported(path string) error {\n    // chmod support test: create and chmod a temp file on the same filesystem\n    f, err := os.CreateTemp(filepath.Dir(path), \".modetest*\")\n    if err != nil {\n        return err\n    }\n    defer os.Remove(f.Name()); defer f.Close()\n    return os.Chmod(f.Name(), 0o600) // fails early on NFS/CIFS that reject chmod\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"error setting directory permission mode\") {\n    log.Warn(\"chmod unsupported or failed on target filesystem; verify mount type\", \"err\", err)\n    // fall back to requesting the volume on a local path\n}","preventionTips":["Place host volumes on local POSIX filesystems (ext4/xfs), not NFS/CIFS/FAT.","Avoid mounts mounted with options that strip POSIX semantics.","Ensure the nomad user creates the directory so it owns it (chmod by non-owner fails).","Prevent external cleanup processes from racing with volume creation."],"tags":["filesystem","chmod","permissions","host-volumes","go"],"backgroundTag":"chmod-permission-denied","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}