hashicorp/nomad · error
error creating directory: %w
Error message
error creating directory: %w
What it means
This error wraps the failure of os.MkdirAll when a host volume plugin's Create operation tries to create the requested directory on the client. It means the directory could not be created at the requested path with the requested mode — the wrapped cause (permission denied, path exists as a file, nonexistent parent, full disk, etc.) is included via %w. Nomad logs the raw error and returns this wrapped error to the caller (the host volume manager), which surfaces it in the volume create RPC result.
Source
Thrown at client/hostvolumemanager/host_volume_plugin.go:136
if _, err := os.Stat(path); err == nil {
// already exists
return resp, nil
} else if !os.IsNotExist(err) {
// doesn't exist, but some other path error
log.Error("error with path", "error", err)
return nil, err
}
params, err := decodeMkdirParams(req.Parameters)
if err != nil {
log.Error("error with parameters", "error", err)
return nil, err
}
err = os.MkdirAll(path, params.Mode)
if err != nil {
log.Error("error creating directory", "error", err)
return nil, fmt.Errorf("error creating directory: %w", err)
}
// os.MkdirAll perms are applied after umask, so the new directory may not
// have the exact permissions requested.
err = os.Chmod(path, params.Mode)
if err != nil {
log.Error("error setting directory permission mode", "error", err)
return nil, fmt.Errorf("error setting directory permission mode: %w", err)
}
if runtime.GOOS != "windows" {
// Chown note: A uid or gid of -1 means to not change that value.
if err = os.Chown(path, params.Uid, params.Gid); err != nil {
log.Error("error changing owner/group", "error", err, "uid", params.Uid, "gid", params.Gid)
// Failing to change ownership is fatal for this plugin. Since we have
// already created the directory, we should attempt to clean it.
// Otherwise, the operator must do this manually.View on GitHub (pinned to 482b49bf1a)
Solutions
- Check the wrapped cause (errors.Unwrap / %v of err) and fix the underlying OS problem — most often chown/chmod the parent directory so the nomad client user can create the path.
- Verify no regular file occupies the requested path (ls -l the path; remove or choose a different path).
- Confirm the parent directory chain exists and is on a writable filesystem (not read-only mount, not full disk: df, mount).
- If SELinux/AppArmor is enforcing, add appropriate policy or choose another path.
Example fix
// before: plugin fails because client user cannot write to parent
params := api.HostVolumeCreateParams{ Path: "/volumes/teamdata", Mode: 0o755 }
// after: pre-create and own the parent as an operator
// sudo mkdir -p /volumes && sudo chown nomad:nomad /volumes
params := api.HostVolumeCreateParams{ Path: "/volumes/teamdata", Mode: 0o755 } Defensive patterns
Strategy: validation
Validate before calling
import "os"
func canCreateDir(path string) error {
if fi, err := os.Lstat(path); err == nil && !fi.IsDir() {
return fmt.Errorf("%s exists and is not a directory", path)
}
parent := filepath.Dir(path)
if fi, err := os.Stat(parent); err != nil || !fi.IsDir() {
return fmt.Errorf("parent %s missing or not a directory", parent)
}
f, err := os.CreateTemp(parent, ".wtest*")
if err != nil {
return fmt.Errorf("no write permission in %s: %w", parent, err)
}
f.Close(); os.Remove(f.Name())
return nil
} Try / catch
var hvErr *hvapi.Error
if errors.As(err, &hvErr) && strings.Contains(hvErr.Error(), "error creating directory") {
var pathErr *os.PathError
if errors.As(errors.Unwrap(err), &pathErr) && errors.Is(pathErr.Err, fs.ErrPermission) {
// escalate to operator: fix ownership/permissions of parent
}
} Prevention
- Pre-create and chown the parent volume root directory for the nomad client user during provisioning.
- Ensure the requested volume path does not collide with existing files.
- Keep volume paths on local POSIX filesystems, not read-only or exotic mounts.
- Run the nomad client with sufficient privileges for the directories it must manage.
When it happens
Trigger: Calling the plugin Create operation (HostVolumePlugin.Create, reached via client host volume manager) where os.MkdirAll(path, params.Mode) fails: parent directory missing and cannot be created, permission denied on the target path, a non-directory file already exists at path, path is invalid/too long, or the filesystem is read-only or full.
Common situations: Operator submits a host volume create request with a path under a directory the nomad client user cannot write to (e.g. /var/lib/volumes owned by root); a regular file already exists at the requested path; the volume path points to a read-only mount or NFS export without write access; SELinux/AppArmor blocking mkdir.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- error setting directory permission mode: %w
- error creating task %q dir: %w
- error changing owner/group: %w
- %w: %q
- cannot create copy - %s
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/370b732ffd094abe.
Report an issue: GitHub.