hashicorp/nomad · error
Action %s validation failed: %s
Error message
Action %s validation failed: %s
What it means
Task.Validate wraps each action (task event handler) validation failure as "Action %s validation failed: %s" and appends it to the multi-error. Action.Validate checks the action's name and command fields. It surfaces through job validation and CLI error output.
Source
Thrown at nomad/structs/structs.go:8351
for idx, tmpl := range t.Templates {
if err := tmpl.Validate(); err != nil {
outer := fmt.Errorf("Template %d validation failed: %s", idx+1, err)
mErr.Errors = append(mErr.Errors, outer)
}
if other, ok := destinations[tmpl.DestPath]; ok {
outer := fmt.Errorf("Template %d has same destination as %d", idx+1, other)
mErr.Errors = append(mErr.Errors, outer)
} else {
destinations[tmpl.DestPath] = idx + 1
}
}
// Validate actions.
actions := make(map[string]bool)
for _, action := range t.Actions {
if err := action.Validate(); err != nil {
outer := fmt.Errorf("Action %s validation failed: %s", action.Name, err)
mErr.Errors = append(mErr.Errors, outer)
}
if handled, seen := actions[action.Name]; seen && !handled {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Action %s defined multiple times", action.Name))
actions[action.Name] = true
continue
}
actions[action.Name] = false
}
// Validate the dispatch payload block if there
if t.DispatchPayload != nil {
if err := t.DispatchPayload.Validate(); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Dispatch Payload validation failed: %v", err))
}
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Read the wrapped inner error to identify the bad action field
- Set a valid non-empty `command` and a well-formed `name` on the action block
- Run `nomad job validate` on the job file before submitting
Example fix
// before
action "restart" {
}
// after
action "restart" {
command = "/bin/restart.sh"
} Defensive patterns
Strategy: validation
Validate before calling
for _, a := range task.Actions {
if err := a.Validate(); err != nil {
return fmt.Errorf("action %q: %w", a.Name, err)
}
} Type guard
func actionValid(a *structs.TaskAction) bool { return a.Validate() == nil } Try / catch
if err := job.Validate(); err != nil {
if strings.Contains(err.Error(), "Action ") && strings.Contains(err.Error(), "validation failed") { /* fix action fields */ }
} Prevention
- Always set command on action blocks
- Use kebab-case action names without spaces
- Validate generated HCL before dispatch
When it happens
Trigger: A job task defines an `action` block whose Validate fails: empty or malformed name, empty command, or other invalid action fields.
Common situations: Omitting the action's `command`; using a name with invalid characters; HCL templating producing an empty command string; upgrading jobs between Nomad versions where action validation tightened.
Related errors
- Task group %s validation failed: %v
- Job type %q does not allow update block
- Job type %q does not allow migrate block
- Task group scaling policy validation failed: %v
- Task %s validation failed: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/c471706a1918bdf4.
Report an issue: GitHub.