{"record":{"id":"945ca5dd5f576b91","repo":"hashicorp/nomad","slug":"update-hook-q-failed-v","errorCode":null,"errorMessage":"update hook %q failed: %v","messagePattern":"update hook %q failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocrunner/alloc_runner_hooks.go","lineNumber":247,"sourceCode":"\t\tAllocEnv: allocEnv,\n\t}\n\n\tvar merr multierror.Error\n\tfor _, hook := range ar.runnerHooks {\n\t\th, ok := hook.(interfaces.RunnerUpdateHook)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tname := h.Name()\n\t\tvar start time.Time\n\t\tif ar.logger.IsTrace() {\n\t\t\tstart = time.Now()\n\t\t\tar.logger.Trace(\"running update hook\", \"name\", name, \"start\", start)\n\t\t}\n\n\t\tif err := h.Update(req); err != nil {\n\t\t\tmerr.Errors = append(merr.Errors, fmt.Errorf(\"update hook %q failed: %v\", name, err))\n\t\t}\n\n\t\tif ar.logger.IsTrace() {\n\t\t\tend := time.Now()\n\t\t\tar.logger.Trace(\"finished update hooks\", \"name\", name, \"end\", end, \"duration\", end.Sub(start))\n\t\t}\n\t}\n\n\treturn merr.ErrorOrNil()\n}\n\n// postrun is used to run the runners postrun hooks.\n// all hooks will run, even if any of them fail, and return a multierror, single error, or nil.\nfunc (ar *allocRunner) postrun() error {\n\tif ar.logger.IsTrace() {\n\t\tstart := time.Now()\n\t\tar.logger.Trace(\"running post-run hooks\", \"start\", start)\n\t\tdefer func() {","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocrunner/alloc_runner_hooks.go#L229-L265","documentation":"When an allocation receives an update, each hook's Update(req) is invoked; errors are accumulated (not aborting the first) into a multierror as \"update hook \\\"<name>\\\" failed: <cause>\". This means a hook could not apply the updated alloc (e.g. task group change) — the alloc update is degraded.","triggerScenarios":"handleAllocUpdate → update runs on alloc change; any hook whose Update errors, e.g. task runner update failing to adjust resources, service hook failing to re-register checks, or script check hooks failing.","commonSituations":"In-place deployment where a task can't be updated (image pull error on new version); Consul/Nomad service registration failure during service update; volatile environment (network blip) during update; resource change rejected by driver.","solutions":["Read the hook name and wrapped cause from the aggregated multierror (alloc runner logs include it)","Check whether the new task version's image/artifact is pullable; fix and trigger another deployment","Verify Consul service/registration configuration if a service hook failed","Re-run the deployment or restart the alloc (nomad alloc restart / job stop-start) to re-apply the update"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"alloc, _, err := client.Allocations().Info(ctx, allocID, nil)\nif err == nil {\n  for _, e := range alloc.TaskEvents {\n    if e.DisplayMessage != \"\" { log.Printf(\"alloc event: %s\", e.DisplayMessage) }\n  }\n}","typeGuard":null,"tryCatchPattern":"if err := triggerUpdate(allocID, desired); err != nil {\n  if isHookUpdateFailure(err) { // multierror containing \"update hook\" text\n    time.Sleep(backoff); return triggerUpdate(allocID, desired) // idempotent re-apply\n  }\n}","preventionTips":["Ensure Consul/services endpoints are healthy during deployments","Verify new task versions' images/artifacts are pullable from all client nodes","Watch alloc runner logs during in-place updates to catch failing hooks early"],"tags":["nomad","client","hooks","update","lifecycle"],"backgroundTag":"lifecycle-hook-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"}