{"record":{"id":"ec01a99f0d8c4dd5","repo":"hashicorp/nomad","slug":"pre-run-hook-q-failed-v","errorCode":null,"errorMessage":"pre-run hook %q failed: %v","messagePattern":"pre-run hook %q failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"client/allocrunner/alloc_runner_hooks.go","lineNumber":196,"sourceCode":"\t\tname := pre.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 pre-run hook\", \"name\", name, \"start\", start)\n\t\t}\n\n\t\t// If the operator has disabled hook metrics, then don't call the time\n\t\t// function to save 30ns per hook.\n\t\tvar hookExecutionStart time.Time\n\n\t\tif !ar.clientConfig.DisableAllocationHookMetrics {\n\t\t\thookExecutionStart = time.Now()\n\t\t}\n\n\t\terr := pre.Prerun(allocEnv)\n\t\tar.hookStatsHandler.Emit(hookExecutionStart, name, \"prerun\", err)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"pre-run 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 pre-run hook\", \"name\", name, \"end\", end, \"duration\", end.Sub(start))\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// update runs the alloc runner update hooks. Update hooks are run\n// asynchronously with all other alloc runner operations.\nfunc (ar *allocRunner) update(update *structs.Allocation) error {\n\tif ar.logger.IsTrace() {\n\t\tstart := time.Now()\n\t\tar.logger.Trace(\"running update hooks\", \"start\", start)\n\t\tdefer func() {","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocrunner/alloc_runner_hooks.go#L178-L214","documentation":"While starting an allocation, the prerun phase runs each lifecycle pre-run hook (alloc directory, task runners setup, scripts, etc.). If any hook's Prerun returns an error, prerun aborts immediately and wraps it with the hook name and cause. The alloc fails and is rescheduled depending on failure handling settings.","triggerScenarios":"Any hook registered in initRunnerHooks whose Prerun(allocEnv) errors — e.g. mkdir/persist of alloc/task directories fails, script hooks fail, task runner prerun (image pull, chroot setup) fails.","commonSituations":"Disk full or permissions issues on data_dir/alloc_dir; Docker image pull failures; host volume paths not existing or unreadable; SELinux/AppArmor denials; NFS mount problems on the client host.","solutions":["Read the hook name in the message and the wrapped cause (e.g. image pull failure, mkdir permission denied)","Check disk space and permissions on the client's data_dir/alloc_dir","Verify referenced host volumes, artifacts, and container images are reachable/valid","Use `nomad alloc status` and client logs for the failing hook's detailed error; fix root cause and reschedule"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// preflight checks before deploy\ndf -h /var/lib/nomad   // disk space\nls -ld $NOMAD_DATA_DIR/alloc // permissions\ncurl -I $ARTIFACT_URL // artifacts reachable","typeGuard":null,"tryCatchPattern":"if _, err := client.Allocations().Info(ctx, allocID, nil); err != nil {\n  // inspect alloc events for the failing hook name\n  for _, ev := range alloc.TaskEvents { log.Printf(\"%s: %s\", ev.Type, ev.DisplayMessage) }\n}","preventionTips":["Monitor client disk space and alloc_dir permissions","Pre-pull/verify container images and artifacts before deployment","Check host volume paths exist and are readable on every client node"],"tags":["nomad","client","hooks","lifecycle","prerun"],"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"}