hashicorp/nomad · error
can only use change_signal=%q with change_mode=%q
Error message
can only use change_signal=%q with change_mode=%q
What it means
WorkloadIdentity.Validate returns this error when ChangeSignal is set while ChangeMode is empty, "noop", or "restart". change_signal only makes sense with change_mode = "signal"; otherwise the signal would never be delivered, so Nomad flags the combination as invalid.
Source
Thrown at nomad/structs/workload_id.go:473
var mErr multierror.Error
if !validIdentityName.MatchString(wi.Name) {
err := fmt.Errorf("invalid name %q. Must match regex %s", wi.Name, validIdentityName)
mErr.Errors = append(mErr.Errors, err)
}
for i, aud := range wi.Audience {
if aud == "" {
mErr.Errors = append(mErr.Errors, fmt.Errorf("an empty string is an invalid audience (%d)", i+1))
}
}
switch wi.ChangeMode {
case "", WIChangeModeNoop, WIChangeModeRestart:
// Treat "" as noop. Make sure signal isn't set.
if wi.ChangeSignal != "" {
mErr.Errors = append(mErr.Errors, fmt.Errorf("can only use change_signal=%q with change_mode=%q",
wi.ChangeSignal, WIChangeModeSignal))
}
case WIChangeModeSignal:
if wi.ChangeSignal == "" {
mErr.Errors = append(mErr.Errors, fmt.Errorf("change_signal must be specified when using change_mode=%q", WIChangeModeSignal))
}
default:
// Unknown change_mode
mErr.Errors = append(mErr.Errors, fmt.Errorf("invalid change_mode: %s", wi.ChangeMode))
}
if wi.TTL > 0 && (wi.Name == "" || wi.Name == WorkloadIdentityDefaultName) {
mErr.Errors = append(mErr.Errors, fmt.Errorf("ttl for default identity not yet supported"))
}
if wi.TTL < 0 {
mErr.Errors = append(mErr.Errors, fmt.Errorf("ttl must be >= 0"))
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Set change_mode = "signal" so the change_signal is actually used.
- Or remove the change_signal field if you intend noop/restart behavior.
- Validate the full identity locally — the error names both the signal and the required mode.
Example fix
// before change_mode = "restart" change_signal = "SIGHUP" // after change_mode = "signal" change_signal = "SIGHUP"
Defensive patterns
Strategy: validation
Validate before calling
if wi.ChangeSignal != "" && wi.ChangeMode != "signal" {
return fmt.Errorf("change_signal requires change_mode = signal")
} Prevention
- Only set change_signal together with change_mode = "signal".
- Remove change_signal when switching to restart/noop modes.
- Lint job templates for orphaned change_signal fields.
When it happens
Trigger: Validate() on a WorkloadIdentity where ChangeSignal != "" but ChangeMode is "", WIChangeModeNoop, or WIChangeModeRestart — e.g. a job spec with change_signal = "SIGHUP" but no (or a non-signal) change_mode.
Common situations: Copying a signal-handling identity block but changing change_mode to restart; assuming a signal defaults to signal mode; leftover change_signal after removing change_mode = "signal".
Related errors
- change_signal must be specified when using change_mode=%q
- file parameter must be true in order to specify filepath
- wait config is nil or 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/acc7c4d3a92bd77a.
Report an issue: GitHub.