hashicorp/nomad · error
Must specify signal value when change mode is signal
Error message
Must specify signal value when change mode is signal
What it means
Template.Validate() enforces that when a template's change_mode is "signal", a change_signal must be provided, because Nomad needs to know which signal to send to the task on template change. Empty ChangeSignal with ChangeModeSignal yields this error in the validation multierror.
Source
Thrown at nomad/structs/structs.go:8985
// Verify we can render somewhere
if t.DestPath == "" {
_ = multierror.Append(&mErr, fmt.Errorf("Must specify a destination for the template"))
}
// Verify the destination doesn't escape
escaped, err := escapingfs.PathEscapesAllocViaRelative("task", t.DestPath)
if err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("invalid destination path: %v", err))
} else if escaped {
mErr.Errors = append(mErr.Errors, fmt.Errorf("destination escapes allocation directory"))
}
// Verify a proper change mode
switch t.ChangeMode {
case TemplateChangeModeNoop, TemplateChangeModeRestart:
case TemplateChangeModeSignal:
if t.ChangeSignal == "" {
_ = multierror.Append(&mErr, fmt.Errorf("Must specify signal value when change mode is signal"))
}
if t.Envvars {
_ = multierror.Append(&mErr, fmt.Errorf("cannot use signals with env var templates"))
}
case TemplateChangeModeScript:
if t.ChangeScript == nil {
_ = multierror.Append(&mErr, fmt.Errorf("must specify change script configuration value when change mode is script"))
}
if err = t.ChangeScript.Validate(); err != nil {
_ = multierror.Append(&mErr, err)
}
default:
_ = multierror.Append(&mErr, TemplateChangeModeInvalidError)
}
// Verify the splay is positive
if t.Splay < 0 {View on GitHub (pinned to 482b49bf1a)
Solutions
- Add a change_signal, e.g. template { change_mode = "signal" change_signal = "SIGHUP" }.
- Or switch change_mode to "restart" (or remove change_mode to use the default) if signaling is not needed.
- Verify the chosen signal is one the task's process actually handles.
Example fix
// before
template {
data = "..."
destination = "local/app.conf"
change_mode = "signal"
}
// after
template {
data = "..."
destination = "local/app.conf"
change_mode = "signal"
change_signal = "SIGHUP"
} Defensive patterns
Strategy: validation
Validate before calling
// Pre-submit check
if tpl.ChangeMode == "signal" && tpl.ChangeSignal == "" {
return errors.New("change_mode=signal requires change_signal")
} Prevention
- Set change_signal whenever change_mode = "signal" (commonly SIGHUP for config reloads).
- Prefer change_mode = "restart" when no signal handler exists in the app.
- Verify the app process actually handles the signal you configure.
When it happens
Trigger: Submitting a job with template { change_mode = "signal" } but no change_signal set (t.ChangeSignal == ""). Triggered in the switch over t.ChangeMode in Template.Validate().
Common situations: Setting change_mode = "signal" copied from an example but forgetting the change_signal line; renaming the template and losing the signal field; assuming a default signal exists (there is none for signal mode).
Related errors
- Failed to parse signal %q
- Must specify a source path or have an embedded template
- Must specify a destination for the template
- template source path escapes alloc directory
- template destination path escapes alloc directory
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/5dd39673a28855f2.
Report an issue: GitHub.