{"record":{"id":"baff4157020266b7","repo":"hashicorp/nomad","slug":"post-run-hook-q-failed-w","errorCode":null,"errorMessage":"post-run hook %q failed: %w","messagePattern":"post-run hook %q failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocrunner/alloc_runner_hooks.go","lineNumber":286,"sourceCode":"\t\t}()\n\t}\n\n\tvar merr multierror.Error\n\tfor _, hook := range ar.runnerHooks {\n\t\tpost, ok := hook.(interfaces.RunnerPostrunHook)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tname := post.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 post-run hook\", \"name\", name, \"start\", start)\n\t\t}\n\n\t\tif err := post.Postrun(); err != nil {\n\t\t\tmerr.Errors = append(merr.Errors, fmt.Errorf(\"post-run hook %q failed: %w\", 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 post-run hooks\", \"name\", name, \"end\", end, \"duration\", end.Sub(start))\n\t\t}\n\t}\n\n\treturn helper.FlattenMultierror(merr.ErrorOrNil())\n}\n\n// destroy is used to run the runners destroy hooks. All hooks are run and\n// errors are returned as a multierror.\nfunc (ar *allocRunner) destroy() error {\n\tif ar.logger.IsTrace() {\n\t\tstart := time.Now()\n\t\tar.logger.Trace(\"running destroy hooks\", \"start\", start)\n\t\tdefer func() {","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocrunner/alloc_runner_hooks.go#L268-L304","documentation":"During alloc shutdown, each post-run hook's Postrun() is executed and any error is accumulated into a multierror wrapped as \"post-run hook \\\"<name>\\\" failed: <cause>\". This indicates cleanup (e.g. directory cleanup, network teardown) failed while stopping the allocation.","triggerScenarios":"Run() → postrun after task runners stop; any hook with Postrun() errors, e.g. alloc dir cleanup hook failing to remove directories or network isolation teardown failing.","commonSituations":"Files inside alloc_dir held open or mounted (won't unmount/remove) by leftover processes; permission errors on cleanup; CNI network teardown failure; disk I/O errors on the client host.","solutions":["Identify the failing hook from the message and the wrapped cause","Check for leftover processes holding files/mounts in the alloc directory (lsof/grep mounts) and kill them","Manually clean stale alloc dirs under the client data_dir if safe, and verify client disk/permissions","Check CNI plugin health if the failure is network teardown; upgrade/fix plugins and garbage-collect (nomad system gc)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := stopAlloc(allocID); err != nil {\n  if strings.Contains(err.Error(), \"post-run hook\") {\n    // cleanup failed: inspect alloc dir mounts and CNI, then garbage collect\n    nomadSystemGC()\n  }\n}","preventionTips":["Ensure tasks terminate cleanly (kill_timeout, shutdown signals) so files are released before cleanup","Monitor for leaked mounts/processes in the client alloc_dir","Keep CNI plugins healthy and run periodic `nomad system gc`"],"tags":["nomad","client","hooks","postrun","cleanup"],"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"}