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
- Make all template stanzas in the task agree on `once`: either add `once = true` to every template or remove it from all.
- If only one template needs one-shot rendering, split it into a separate task (each task gets its own template manager).
- 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
- Normalize the Once field across templates before constructing the manager.
- Validate job specs (HCL/JSON) so all template stanzas in a task share the same `once` value.
- If per-template one-shot rendering is needed, use separate tasks.
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
- Failed to parse signal %q
- wait config is nil or empty
- wait config is empty
- missing datacenter for client registration
- default_identity_ttl must be greater than 0
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/19ddbd6dba03e786.
Report an issue: GitHub.