hashicorp/nomad · error

All templates should have same Once value

Error message

All templates should have same Once value

What it means

Validate() enforces that every template in c.Templates has the same value for the Once field, because Once is conceptually a runner-level setting in consul-template but Nomad sets it per template. Mixed values are ambiguous, so the config is rejected.

Source

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

		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
}

func (c *TaskTemplateManagerConfig) OnceModeEnabled() bool {
	return len(c.Templates) > 0 && c.Templates[0].Once
}

func NewTaskTemplateManager(config *TaskTemplateManagerConfig) (*TaskTemplateManager, error) {
	// Check pre-conditions
	if err := config.Validate(); err != nil {
		return nil, err
	}

	tm := &TaskTemplateManager{
		config:     config,

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Make all template stanzas in the task agree on `once`: either add `once = true` to every template or remove it from all.
  2. If only one template needs one-shot rendering, split it into a separate task (each task gets its own template manager).
  3. Programmatically, normalize t.Once across the slice before constructing the manager.

Example fix

// before (job HCL)
template { data = "a"; once = true  }
template { data = "b" }
// after
template { data = "a"; once = true }
template { data = "b"; once = true }
Defensive patterns

Strategy: validation

Validate before calling

var once *bool
for i := range cfg.Templates {
    v := cfg.Templates[i].Once
    if once == nil { once = &v } else if v != *once {
        return fmt.Errorf("all templates must agree on `once`")
    }
}

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 Templates slice where at least one template block has `once = true` while another has `once = false` (or is unset, defaulting to false).

Common situations: A Nomad job spec where only some `template` stanzas in the same task set `once = true`; programmatic template generation that toggles Once per template.

Related errors


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