hashicorp/nomad · error

work_dir must be an absolute path

Error message

work_dir must be an absolute path

What it means

rawexec's TaskConfig.validate() requires work_dir, when set, to be an absolute filesystem path, because the driver chdir()s the spawned process into it directly; a relative path has no meaningful anchor since the working directory of the Nomad client process is arbitrary.

Source

Thrown at drivers/rawexec/driver.go:201

	// WorkDir sets the working directory of the task
	WorkDir string `codec:"work_dir"`

	//DeniedEnvvars enables the removal of specified environment variables from a given job environment
	DeniedEnvvars []string `codec:"denied_envvars"`
}

func (t *TaskConfig) validate() error {
	// ensure only one of cgroups_v1_override and cgroups_v2_override have been
	// configured; must check here because task config validation cannot happen
	// on the server.
	if len(t.OverrideCgroupV1) > 0 && t.OverrideCgroupV2 != "" {
		return errors.New("only one of cgroups_v1_override and cgroups_v2_override may be set")
	}
	if t.OOMScoreAdj < 0 {
		return errors.New("oom_score_adj must not be negative")
	}
	if t.WorkDir != "" && !filepath.IsAbs(t.WorkDir) {
		return errors.New("work_dir must be an absolute path")
	}
	return nil
}

// TaskState is the state which is encoded in the handle returned in
// StartTask. This information is needed to rebuild the task state and handler
// during recovery.
type TaskState struct {
	ReattachConfig *pstructs.ReattachConfig
	TaskConfig     *drivers.TaskConfig
	Pid            int
	StartedAt      time.Time
}

// NewRawExecDriver returns a new DriverPlugin implementation
func NewRawExecDriver(ctx context.Context, logger hclog.Logger) drivers.DriverPlugin {
	logger = logger.Named(pluginName)
	return &Driver{

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Prefix the path with "/" or the Windows drive root, e.g. work_dir = "/opt/myapp"
  2. Use the allocation directory variable (NOMAD_ALLOC_DIR or driver-relative env) to build an absolute path in the template
  3. Omit work_dir to run with the executor default working directory
  4. Verify the path exists and is accessible to the Nomad client user

Example fix

// before
config {
  command = "/bin/app"
  work_dir = "appdir"
}
// after
config {
  command = "/bin/app"
  work_dir = "/opt/appdir"
}
Defensive patterns

Strategy: validation

Validate before calling

func checkWorkDir(wd string) error {
    if wd != "" && !filepath.IsAbs(wd) {
        return fmt.Errorf("work_dir %q must be absolute", wd)
    }
    return nil
}

Type guard

func isAbsWorkDir(wd string) bool { return wd == "" || filepath.IsAbs(wd) }

Prevention

When it happens

Trigger: Submitting a rawexec task with work_dir = "subdir" or any path not starting with "/" (on Windows, not matching a root like C:\\); validate() rejects it before the task starts.

Common situations: Porting configs that used relative paths with a different executor; templates interpolating a relative directory name; assuming the driver resolves work_dir relative to the task's allocation dir.

Related errors


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