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

  1. Add a change_signal, e.g. template { change_mode = "signal" change_signal = "SIGHUP" }.
  2. Or switch change_mode to "restart" (or remove change_mode to use the default) if signaling is not needed.
  3. 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

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


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