hashicorp/nomad · error

task.Resources is empty

Error message

task.Resources is empty

What it means

createContainerConfig guards against a drivers.TaskConfig with nil Resources, which should be impossible for a scheduled task since Nomad always allocates resources. If reached, the driver cannot compute memory/CPU limits for the container and refuses to start it. A structured log is emitted alongside the error.

Source

Thrown at drivers/docker/driver.go:1034

	}

	return idset.Parse[hw.CoreID](string(b)).String(), nil
}

func (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *TaskConfig,
	imageID string) (createContainerOptions, error) {

	logger := d.logger.With("task_name", task.Name)
	c := createContainerOptions{}

	// ensure that PortMap variables are populated early on
	task.Env = taskenv.SetPortMapEnvs(task.Env, driverConfig.PortMap)

	if task.Resources == nil {
		// Guard against missing resources. We should never have been able to
		// schedule a job without specifying this.
		logger.Error("task.Resources is empty")
		return c, fmt.Errorf("task.Resources is empty")
	}

	memory, memoryReservation := memoryLimits(driverConfig.MemoryHardLimit,
		task.Resources.NomadResources.Memory)
	if memory > 0 && memoryReservation > memory {
		return c, fmt.Errorf("task memory requirements exceed driver hard limit of %d MB",
			driverConfig.MemoryHardLimit)
	}

	binds, err := d.containerBinds(task, driverConfig)
	if err != nil {
		return c, err
	}
	logger.Trace("binding volumes", "volumes", binds)

	// create the config block that will later be consumed by go-dockerclient
	config := &containerapi.Config{
		Image:      imageID,

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Populate task.Resources (with NomadResources including Memory and CPU) before calling StartTask.
  2. If using the drivers/testutils TaskConfig helper, set resources explicitly rather than relying on defaults.
  3. If this occurs for a normal job submission, file a Nomad issue — scheduled tasks must always carry resources; include the alloc ID and Nomad version.

Example fix

// test harness
// before
taskCfg := drivers.NewTaskConfig("alloc", "task")
// after
taskCfg.Resources = &drivers.Resources{NomadResources: &structs.Resources{Memory: 128, CPU: 100}}
Defensive patterns

Strategy: type-guard

Validate before calling

function assertTaskResources(task) {
  if (!task || !task.Resources) throw new Error('TaskConfig.Resources must be set before StartTask');
}

Type guard

function hasResources(task) {
  return task != null && task.Resources != null
    && typeof task.Resources.NomadResources === 'object';
}

Try / catch

try {
  await driver.StartTask(cfg);
} catch (err) {
  if (/task\.Resources is empty/.test(err.message)) {
    throw new Error('build TaskConfig with Resources populated (NomadResources.Memory/CPU)');
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling the docker driver's StartTask (or its internal createContainerConfig) programmatically with a hand-constructed TaskConfig that never had Resources populated — typical of tests, plugins, or tooling driving the driver API directly.

Common situations: Custom tooling or unit tests building TaskConfig manually and forgetting task.Resources = &drivers.Resources{...}; an upstream Nomad bug/regression in task config construction.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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