hashicorp/nomad · error

failed to create exec object: %v

Error message

failed to create exec object: %v

What it means

During drivers.ExecTask, the handle first creates a Docker exec instance inside the running container via ExecCreate. If the Docker Engine API rejects that call, the driver wraps the failure as 'failed to create exec object'. Nothing was executed; this is a setup-stage failure before attach or output capture.

Source

Thrown at drivers/docker/handle.go:97

		s.ReattachConfig = pstructs.ReattachConfigFromGoPlugin(h.dloggerPluginClient.ReattachConfig())
	}
	return s
}

func (h *taskHandle) Exec(ctx context.Context, cmd string, args []string) (*drivers.ExecTaskResult, error) {
	fullCmd := make([]string, len(args)+1)
	fullCmd[0] = cmd
	copy(fullCmd[1:], args)
	createExecOpts := mclient.ExecCreateOptions{
		AttachStdin:  false,
		AttachStdout: true,
		AttachStderr: true,
		TTY:          false,
		Cmd:          fullCmd,
	}
	exec, err := h.dockerClient.ExecCreate(ctx, h.containerID, createExecOpts)
	if err != nil {
		return nil, fmt.Errorf("failed to create exec object: %v", err)
	}

	execResult := &drivers.ExecTaskResult{ExitResult: &drivers.ExitResult{}}
	stdout, _ := circbuf.NewBuffer(int64(drivers.CheckBufSize))
	stderr, _ := circbuf.NewBuffer(int64(drivers.CheckBufSize))
	startOpts := mclient.ExecAttachOptions{TTY: false}

	// hijack exec output streams
	hijacked, err := h.dockerClient.ExecAttach(ctx, exec.ID, startOpts)
	if err != nil {
		return nil, fmt.Errorf("failed to attach to exec object: %w", err)
	}

	_, err = stdcopy.StdCopy(stdout, stderr, hijacked.Reader)
	if err != nil {
		return nil, err
	}
	defer hijacked.Close()

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify the task/container is running ('docker ps', 'nomad alloc status') before exec; restart the task if it exited.
  2. Check Docker daemon health and socket permissions on the host (systemctl status docker, /var/run/docker.sock access).
  3. Confirm the Docker API version used by the nomad docker driver is compatible with the engine (API version negotiation/mismatch).
  4. Retry the exec; transient daemon errors often resolve after the engine recovers.

Example fix

// before: exec on possibly-stopped allocation
nomad alloc exec <alloc> <cmd>
// after: guard by checking task state first
nomad alloc status <alloc>   # ensure task is 'running'
nomad alloc exec <alloc> <cmd>
Defensive patterns

Strategy: retry

Validate before calling

// check the allocation's task state before exec
// nomad alloc status <alloc> -> task state must be 'running'

Try / catch

for i := 0; i < 3; i++ {
    res, err := driver.ExecTask(ctx, taskID, opts)
    if err == nil {
        break
    }
    if strings.Contains(err.Error(), "failed to create exec object") {
        time.Sleep(2*time.Second)
        continue
    }
    return err
}

Prevention

When it happens

Trigger: h.dockerClient.ExecCreate(ctx, h.containerID, createExecOpts) returns an error: container no longer running/removed, invalid command slice, Docker daemon unreachable, or API permission denied (e.g. non-root user without exec privileges).

Common situations: nomad alloc exec run against a dead/exited task; container was garbage-collected between list and exec; Docker daemon restarted or socket permissions changed; Docker API version mismatch between the plugin's client and the engine.

Related errors


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