{"record":{"id":"04bb3791e1157f86","repo":"hashicorp/nomad","slug":"change-signal-must-be-specified-when-using-change","errorCode":null,"errorMessage":"change_signal must be specified when using change_mode=%q","messagePattern":"change_signal must be specified when using change_mode=%q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/workload_id.go","lineNumber":478,"sourceCode":"\t\tmErr.Errors = append(mErr.Errors, err)\n\t}\n\n\tfor i, aud := range wi.Audience {\n\t\tif aud == \"\" {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"an empty string is an invalid audience (%d)\", i+1))\n\t\t}\n\t}\n\n\tswitch wi.ChangeMode {\n\tcase \"\", WIChangeModeNoop, WIChangeModeRestart:\n\t\t// Treat \"\" as noop. Make sure signal isn't set.\n\t\tif wi.ChangeSignal != \"\" {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"can only use change_signal=%q with change_mode=%q\",\n\t\t\t\twi.ChangeSignal, WIChangeModeSignal))\n\t\t}\n\tcase WIChangeModeSignal:\n\t\tif wi.ChangeSignal == \"\" {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"change_signal must be specified when using change_mode=%q\", WIChangeModeSignal))\n\t\t}\n\tdefault:\n\t\t// Unknown change_mode\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"invalid change_mode: %s\", wi.ChangeMode))\n\t}\n\n\tif wi.TTL > 0 && (wi.Name == \"\" || wi.Name == WorkloadIdentityDefaultName) {\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"ttl for default identity not yet supported\"))\n\t}\n\n\tif wi.TTL < 0 {\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"ttl must be >= 0\"))\n\t}\n\n\tif wi.Filepath != \"\" && !wi.File {\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"file parameter must be true in order to specify filepath\"))\n\t}\n","sourceCodeStart":460,"sourceCodeEnd":496,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/workload_id.go#L460-L496","documentation":"WorkloadIdentity.Validate requires that when ChangeMode is set to \"signal\", a ChangeSignal must also be provided. Nomad needs to know which signal to send the task when a new identity is rotated. Without a signal the restart-less rotation mechanism is under-specified, so validation rejects the identity.","triggerScenarios":"Submitting a job whose workload identity block has change_mode = \"signal\" but no change_signal field set (ChangeSignal == \"\"), e.g. in a job HCL/JSON spec or when constructing structs.WorkloadIdentity in Go and calling Validate().","commonSituations":"Hand-writing job HCL and forgetting change_signal after setting change_mode = \"signal\"; copying an identity block that used change_mode = \"restart\" and switching it to signal; SDK/Go code setting ChangeMode = WIChangeModeSignal without setting ChangeSignal.","solutions":["Add change_signal (e.g. change_signal = \"SIGHUP\") to the identity block alongside change_mode = \"signal\".","Alternatively drop the change_signal intent and use change_mode = \"restart\" which needs no signal.","If no rotation is desired, omit change_mode entirely (defaults to restart)."],"exampleFix":"// before\nidentity {\n  name = \"aws\"\n  change_mode = \"signal\"\n}\n// after\nidentity {\n  name = \"aws\"\n  change_mode = \"signal\"\n  change_signal = \"SIGHUP\"\n}","handlingStrategy":"validation","validationCode":"func validateChangeSignal(wi *structs.WorkloadIdentity) error {\n  if wi.ChangeMode == structs.WIChangeModeSignal && wi.ChangeSignal == \"\" {\n    return fmt.Errorf(\"change_signal is required when change_mode=%q\", wi.ChangeMode)\n  }\n  return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair change_mode = \"signal\" with a change_signal value in job templates.","Lint job HCL for identity blocks before submission.","Default templates should include change_signal commented next to change_mode."],"tags":["nomad","workload-identity","validation","config"],"backgroundTag":"missing-required-argument","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}