hashicorp/nomad · error

command is required

Error message

command is required

What it means

UniversalExecutor.ExecStreaming validates that the command slice passed for streaming execution is non-empty. An empty command means exec.CommandContext would have no binary to run, so the executor rejects it up front with this error instead of failing later in exec. It is a programmer/config error guard at the entry of the streaming exec API.

Source

Thrown at drivers/shared/executor/executor.go:499

		// Some kind of error happened; default to critical
		exitCode := 2
		if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
			exitCode = status.ExitStatus()
		}

		// Don't return the exitError as the caller only needs the
		// output and code.
		return buf.Bytes(), exitCode, nil
	}
	return buf.Bytes(), 0, nil
}

func (e *UniversalExecutor) ExecStreaming(ctx context.Context, command []string, tty bool,
	stream drivers.ExecTaskStream) error {

	if len(command) == 0 {
		return fmt.Errorf("command is required")
	}

	cmd := exec.CommandContext(ctx, command[0], command[1:]...)

	cmd.Dir = e.childCmd.Dir
	cmd.Env = e.childCmd.Env

	execHelper := &execHelper{
		logger: e.logger,

		newTerminal: func() (func() (*os.File, error), *os.File, error) {
			pty, tty, err := pty.Open()
			if err != nil {
				return nil, nil, err
			}

			return func() (*os.File, error) { return pty, nil }, tty, err
		},

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Ensure the command slice has at least one element before calling ExecStreaming
  2. If building from a string, trim and validate the string is non-empty before splitting
  3. Log the task config that produced the empty command to find the upstream parsing bug

Example fix

// before
exec.ExecStreaming(ctx, cfg.Command, tty, stream) // cfg.Command may be empty
// after
if len(cfg.Command) == 0 {
    return fmt.Errorf("task command is empty; check job config")
}
return exec.ExecStreaming(ctx, cfg.Command, tty, stream)
Defensive patterns

Strategy: validation

Validate before calling

if len(command) == 0 {
    return fmt.Errorf("cannot exec: command slice is empty")
}
return e.ExecStreaming(ctx, command, tty, stream)

Type guard

func hasCommand(cmd []string) bool { return len(cmd) > 0 }

Try / catch

if err := e.ExecStreaming(ctx, command, tty, stream); err != nil {
    if strings.Contains(err.Error(), "command is required") {
        // fix caller config; no retry will help
        return fmt.Errorf("invalid exec request: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ExecStreaming(ctx, nil/[]string{}, tty, stream) or passing a command slice that was produced empty by upstream config parsing (e.g. raw_exec command string split produced no tokens).

Common situations: Job/task config with an empty 'command' field; splitting a command string on whitespace where the string is blank; templating that rendered an empty command; tests that forget to populate command.

Related errors


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