hashicorp/nomad · error

error moving task %q local dir: %w

Error message

error moving task %q local dir: %w

What it means

After creating the new task directory, Move renames the previous allocation's task-local directory into it via os.Rename. Failure of that rename (cross-device, permissions, destination conflict) yields 'error moving task %q local dir'. This wraps the raw OS error so the task name is identified.

Source

Thrown at client/allocdir/alloc_dir.go:313

		}
	}

	// Move the task directories
	for _, task := range tasks {
		otherTaskDir := filepath.Join(other.AllocDirPath(), task.Name)
		otherTaskLocal := filepath.Join(otherTaskDir, TaskLocal)

		fileInfo, err := os.Stat(otherTaskLocal)
		if fileInfo != nil && err == nil {
			// TaskDirs haven't been built yet, so create it
			newTaskDir := filepath.Join(a.AllocDir, task.Name)
			if err := os.MkdirAll(newTaskDir, fileMode777); err != nil {
				return fmt.Errorf("error creating task %q dir: %w", task.Name, err)
			}
			localDir := filepath.Join(newTaskDir, TaskLocal)
			os.Remove(localDir) // remove an empty local dir if it exists
			if err := os.Rename(otherTaskLocal, localDir); err != nil {
				return fmt.Errorf("error moving task %q local dir: %w", task.Name, err)
			}
		}
	}

	return nil
}

// Destroy tears down previously build directory structure.
func (a *AllocDir) Destroy() error {
	// Unmount all mounted shared alloc dirs.
	mErr := new(multierror.Error)
	if err := a.UnmountAll(); err != nil {
		mErr = multierror.Append(mErr, err)
	}

	if err := os.RemoveAll(a.AllocDir); err != nil {
		mErr = multierror.Append(mErr, fmt.Errorf("failed to remove alloc dir %q: %w", a.AllocDir, err))
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Ensure both alloc dirs share a filesystem
  2. Stop the old task/allocation before migration so no process holds the local dir
  3. Check permissions on old task local dir and new task dir
  4. Retry if racing with GC; coordinate GC to not delete migrating allocations
Defensive patterns

Strategy: try-catch

Try / catch

if err := allocDir.Move(other, tasks); err != nil && strings.Contains(err.Error(), "error moving task") {
  // ensure old alloc stopped and same-filesystem, then retry
}

Prevention

When it happens

Trigger: os.Rename(otherTaskLocal, localDir) fails — source and target on different devices, the pre-removed localDir path recreated concurrently, or permission denial on either side.

Common situations: Same cross-device mount issues as data-dir moves; lingering handles on the local dir (task still running) preventing atomic rename on some systems; race with node GC removing the old alloc dir.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/948ad52ca5f50141. Report an issue: GitHub.