hashicorp/nomad · error
invalid hook: %v
Error message
invalid hook: %v
What it means
TaskLifecycleConfig.Validate() accepts only the three known hooks: prestart, poststart, poststop. Any other non-empty `hook` string hits the default branch and produces this error with the invalid value interpolated.
Source
Thrown at nomad/structs/structs.go:6189
}
nd := new(TaskLifecycleConfig)
*nd = *d
return nd
}
func (d *TaskLifecycleConfig) Validate() error {
if d == nil {
return nil
}
switch d.Hook {
case TaskLifecycleHookPrestart:
case TaskLifecycleHookPoststart:
case TaskLifecycleHookPoststop:
case "":
return fmt.Errorf("no lifecycle hook provided")
default:
return fmt.Errorf("invalid hook: %v", d.Hook)
}
return nil
}
var (
// These default restart policies needs to be in sync with
// Canonicalize in api/tasks.go
DefaultServiceJobRestartPolicy = RestartPolicy{
Delay: 15 * time.Second,
Attempts: 2,
Interval: 30 * time.Minute,
Mode: RestartPolicyModeFail,
RenderTemplates: false,
}
DefaultBatchJobRestartPolicy = RestartPolicy{
Delay: 15 * time.Second,View on GitHub (pinned to 482b49bf1a)
Solutions
- Use exactly one of `prestart`, `poststart`, or `poststop` (lowercase) for `hook`.
- Check `nomad job validate <file>` output — it echoes the invalid value to identify the typo.
- Verify the Nomad version supports the intended hook (all three exist in supported versions; there is no 'prerestart').
Example fix
// before
lifecycle {
hook = "pre-start"
}
// after
lifecycle {
hook = "prestart"
} Defensive patterns
Strategy: validation
Validate before calling
var validHooks = map[string]bool{"prestart": true, "poststart": true, "poststop": true}
if !validHooks[lc.Hook] {
return fmt.Errorf("invalid hook %q; use prestart|poststart|poststop", lc.Hook)
} Prevention
- Lowercase hook values exactly: prestart, poststart, poststop.
- Do not reuse hook names from other ecosystems (Docker, systemd).
- Keep a shared constant list of valid hooks in tooling that generates Nomad jobs.
When it happens
Trigger: Setting `hook` to a misspelled or unsupported value such as `pre-start`, `PresTart`, `restart`, or `stop` in a task's lifecycle block, then running `nomad job run` or a plan/validate call.
Common situations: Typos or wrong casing; confusing Nomad lifecycle hooks with Docker/systemd hook names; following outdated documentation or examples from other schedulers.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- no lifecycle hook provided
- Disconnect cannot be configured with both lost_after and sto
- lost_after cannot be a negative duration
- stop_after cannot be a negative duration
- Missing job ID
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/6c8e15f65cfe7c72.
Report an issue: GitHub.