{"record":{"id":"9a8be11137cfef7b","repo":"hashicorp/nomad","slug":"failed-to-send-signal-w","errorCode":null,"errorMessage":"failed to send signal: %w","messagePattern":"failed to send signal: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocrunner/taskrunner/vault_hook.go","lineNumber":277,"sourceCode":"\tif err != nil {\n\t\treturn \"\", 0, err\n\t}\n\tif err := h.writeToken(token); err != nil {\n\t\treturn \"\", 0, fmt.Errorf(\"failed to write Vault token to disk: %w\", err)\n\t}\n\n\tvar event *structs.TaskEvent\n\tswitch h.vaultBlock.ChangeMode {\n\tcase structs.VaultChangeModeSignal:\n\t\ts, err := signals.Parse(h.vaultBlock.ChangeSignal)\n\t\tif err != nil {\n\t\t\treturn \"\", 0, fmt.Errorf(\"failed to parse signal: %w\", err)\n\t\t}\n\n\t\tevent := structs.NewTaskEvent(structs.TaskSignaling).\n\t\t\tSetTaskSignal(s).SetDisplayMessage(\"Vault: new Vault token acquired\")\n\t\tif err := h.lifecycle.Signal(event, h.vaultBlock.ChangeSignal); err != nil {\n\t\t\treturn \"\", 0, fmt.Errorf(\"failed to send signal: %w\", err)\n\t\t}\n\tcase structs.VaultChangeModeRestart:\n\t\tevent = structs.NewTaskEvent(structs.TaskRestartSignal).\n\t\t\tSetDisplayMessage(\"Vault: new Vault token acquired\")\n\t\th.lifecycle.Restart(ctx, event, false)\n\tcase structs.VaultChangeModeNoop:\n\t\t// True to its name, this is a noop!\n\tdefault:\n\t\th.logger.Error(\"invalid Vault change mode\", \"mode\", h.vaultBlock.ChangeMode)\n\t}\n\n\th.updater.updatedVaultToken(token)\n\treturn token, time.Second * time.Duration(duration), nil\n}\n\nfunc (h *vaultHook) renewWithBackoff(ctx context.Context, token string) (time.Duration, error) {\n\tvar attempts uint64\n","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocrunner/taskrunner/vault_hook.go#L259-L295","documentation":"After successfully parsing the vault change_signal, the hook calls h.lifecycle.Signal(event, signal) to deliver the signal to the running task. If the task driver fails to send the signal (task already exited, driver does not support signaling), handleRenewalFailure returns this wrapped error.","triggerScenarios":"change_mode = \"signal\" with a valid change_signal, a new Vault token arrives, and lifecycle.Signal returns an error — typically because the task has exited/is not running, or the driver's Signal implementation rejects the call.","commonSituations":"Short-lived tasks that finish before token renewal; drivers without signal support being used with change_mode=signal; task crashed and was mid-restart when the renewed token arrived.","solutions":["Check whether the task exited before the signal was sent; fix the task's crash/exit first","Use change_mode = \"restart\" instead of \"signal\" if the driver does not support signaling","Verify the driver in use implements Signal (e.g. docker/exec do, some raw drivers may not)","Inspect taskrunner/driver logs at the renewal time for the underlying Signal error"],"exampleFix":"// before\nvault {\n  change_mode   = \"signal\"\n  change_signal = \"SIGHUP\"\n}\n// after\nvault {\n  change_mode = \"restart\"\n}","handlingStrategy":"retry","validationCode":"// ensure the driver supports signaling before using change_mode = \"signal\"\ncaps, err := driver.Capabilities()\nif err != nil || !caps.Signal { /* use restart mode instead */ }","typeGuard":null,"tryCatchPattern":"if err := hookSignal(); err != nil {\n    if strings.Contains(err.Error(), \"failed to send signal\") {\n        // task likely exited; wait for restart/retry once\n        time.Sleep(retryDelay)\n        return hookSignal()\n    }\n    return err\n}","preventionTips":["Use change_mode = \"restart\" for tasks that don't handle signals","Keep tasks long-lived if using signal-based token rotation","Monitor task exits around token renewal windows","Verify driver Signal support for your task driver"],"tags":["nomad","vault","signal","driver"],"backgroundTag":"signal-delivery-failed","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"}