hashicorp/nomad · error
Job required for plan
Error message
Job required for plan
What it means
Job.Plan was called without a Job payload. The plan endpoint evaluates a proposed job against the cluster without registering it, so a nil args.Job means there is nothing to evaluate; the request is rejected with 'Job required for plan'.
Source
Thrown at nomad/job_endpoint.go:1777
return nil
}
// Plan is used to cause a dry-run evaluation of the Job and return the results
// with a potential diff containing annotations.
func (j *Job) Plan(args *structs.JobPlanRequest, reply *structs.JobPlanResponse) error {
authErr := j.srv.Authenticate(j.ctx, args)
if done, err := j.srv.forward("Job.Plan", args, args, reply); done {
return err
}
j.srv.MeasureRPCRate("job", structs.RateMetricWrite, args)
if authErr != nil {
return structs.ErrPermissionDenied
}
defer metrics.MeasureSince([]string{"nomad", "job", "plan"}, time.Now())
// Validate the arguments
if args.Job == nil {
return fmt.Errorf("Job required for plan")
}
// Run admission controllers
job, warnings, err := j.admissionControllers(args.Job)
if err != nil {
return err
}
args.Job = job
// Set the warning message
reply.Warnings = helper.MergeMultierrorWarnings(warnings...)
// Check job submission permissions, which we assume is the same for plan
if aclObj, err := j.srv.ResolveACL(args); err != nil {
return err
} else {
if !aclObj.AllowNsOpAnyOf(args.RequestNamespace(),
acl.NamespaceCapabilitySubmitJob,View on GitHub (pinned to 482b49bf1a)
Solutions
- Supply a fully parsed structs.Job in the request body before calling Plan.
- Run 'nomad job validate' / the parse API on the HCL first and abort on parse failure.
- Check that the config file actually loaded (empty file or wrong path yields a nil/empty job).
- Construct the job programmatically and assert non-nil before submitting the plan request.
Example fix
// before
job, err := jobspec.Parse(f) // err ignored, job nil
plan, _, err := client.Jobs().Plan(job, true, nil)
// after
job, err := jobspec.Parse(f)
if err != nil { return err }
if job == nil { return errors.New("parsed job is nil") }
plan, _, err := client.Jobs().Plan(job, true, nil) Defensive patterns
Strategy: validation
Validate before calling
if job == nil {
return fmt.Errorf("nothing to plan: parsed job is nil")
}
if _, _, err := client.Jobs().Validate(job, nil); err != nil { return err }
plan, _, err := client.Jobs().Plan(job, diff, nil) Type guard
func jobProvided(j *api.Job) bool { return j != nil && j.ID != nil && *j.ID != "" } Prevention
- Check errors from job parsing before building plan requests.
- Assert non-nil job after file loads and template expansion.
- Dry-run via the validate endpoint before the plan endpoint.
When it happens
Trigger: POST /v1/job/plan with an empty or missing Job object in the body (client.Jobs().Plan(nil, true, nil)) after ACL checks, at nomad/job_endpoint.go:1777.
Common situations: Dry-run tooling serializing a nil job; HCL/JSON job spec that failed to parse into a structs.Job yet the code proceeded; calling the raw endpoint with an empty POST body.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- missing job ID
- JobID required for actions
- missing node ID
- Missing allocation ID
- Filter expression cannot be used with other filter parameter
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/e4256127085657b4.
Report an issue: GitHub.