hashicorp/nomad · error

Invalid task environment given

Error message

Invalid task environment given

What it means

Validate() requires a non-nil EnvBuilder (*taskenv.Builder) on TaskTemplateManagerConfig. The environment builder is used to expand environment variables in template output paths and to inject rendered values into the task environment. A nil builder makes template rendering unsafe, so the manager refuses to start.

Source

Thrown at client/allocrunner/taskrunner/template/template.go:164

	RenderFunc renderer.Renderer
}

// Validate validates the configuration.
func (c *TaskTemplateManagerConfig) Validate() error {
	if c == nil {
		return fmt.Errorf("Nil config passed")
	} else if c.UnblockCh == nil {
		return fmt.Errorf("Invalid unblock channel given")
	} else if c.Lifecycle == nil {
		return fmt.Errorf("Invalid lifecycle hooks given")
	} else if c.Events == nil {
		return fmt.Errorf("Invalid event hook given")
	} else if c.ClientConfig == nil {
		return fmt.Errorf("Invalid client config given")
	} else if c.TaskDir == "" {
		return fmt.Errorf("Invalid task directory given: %q", c.TaskDir)
	} else if c.EnvBuilder == nil {
		return fmt.Errorf("Invalid task environment given")
	} else if c.MaxTemplateEventRate == 0 {
		return fmt.Errorf("Invalid max template event rate given")
	}

	// Once is a runner config, but in Nomad it is set per template, so all
	// templates given to a runner should have the same value for Once.
	var once bool
	for i, t := range c.Templates {
		if i == 0 {
			once = t.Once
		} else if t.Once != once {
			return fmt.Errorf("All templates should have same Once value")
		}
	}

	return nil
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Construct and assign the *taskenv.Builder for the task before calling NewTaskTemplateManager.
  2. Ensure the task runner builds the env builder (taskenv.NewBuilder with node/alloc config) prior to template manager creation.
  3. In tests, initialize EnvBuilder with taskenv.NewBuilder(...) in the fixture config.

Example fix

// before
cfg := &template.TaskTemplateManagerConfig{
    TaskDir: taskDir,
    ClientConfig: cc,
}
// after
envBuilder := taskenv.NewBuilder(node, alloc, task, region).
    SetHookResources(...)
cfg := &template.TaskTemplateManagerConfig{
    TaskDir: taskDir,
    EnvBuilder: envBuilder,
    ClientConfig: cc,
}
Defensive patterns

Strategy: validation

Validate before calling

if cfg == nil || cfg.EnvBuilder == nil {
    return fmt.Errorf("template manager config needs a non-nil EnvBuilder")
}

Type guard

func hasEnvBuilder(c *template.TaskTemplateManagerConfig) bool { return c != nil && c.EnvBuilder != nil }

Try / catch

tm, err := template.NewTaskTemplateManager(cfg)
if err != nil {
    return fmt.Errorf("creating template manager: %w", err)
}

Prevention

When it happens

Trigger: Calling NewTaskTemplateManager with a config where EnvBuilder was omitted/nil — the caller did not pass the taskenv.Builder built from the task's environment in the task runner setup.

Common situations: Hand-rolled config construction in tests or plugins; refactors where the env builder is created later in the startup sequence than the template manager; forgetting to thread the builder through a wrapper.

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/856af123d6f2474c. Report an issue: GitHub.