hashicorp/nomad · error

missing job for registration

Error message

missing job for registration

What it means

Nomad's job registration endpoint (nomad/job_endpoint.go:123) requires the request to carry a Job object. When JobRegister RPC arrives with args.Job == nil, the server rejects it because there is nothing to register or validate.

Source

Thrown at nomad/job_endpoint.go:123

		return err
	}

	allowedPermissions := []string{acl.NamespaceCapabilityRegisterJob}

	return j.doRegister(aclObj, allowedPermissions, args, reply)
}

// doRegister does the actual job registration, including any additional
// permission checks, and after metrics have begun recording
func (j *Job) doRegister(aclObj *acl.ACL, additionalAllowedPermissions []string, args *structs.JobRegisterRequest, reply *structs.JobRegisterResponse) error {
	if ok, err := registrationsAreAllowed(aclObj, j.srv.State()); !ok || err != nil {
		j.logger.Warn("job registration is currently disabled for non-management ACL")
		return structs.ErrJobRegistrationDisabled
	}

	// Validate the arguments
	if args.Job == nil {
		return fmt.Errorf("missing job for registration")
	}

	// defensive check; http layer and RPC requester should ensure namespaces are set consistently
	if args.RequestNamespace() != args.Job.Namespace {
		return fmt.Errorf("mismatched request namespace in request: %q, %q", args.RequestNamespace(), args.Job.Namespace)
	}

	// Run admission controllers
	job, warnings, err := j.admissionControllers(args.Job)
	if err != nil {
		return err
	}
	args.Job = job

	// Run the submission controller
	warnings = append(warnings, j.submissionController(args))

	// Attach the user token's accessor ID so that deploymentwatcher can

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Populate the Job field of the JobRegisterRequest with a complete *structs.Job before sending (set ID, Name, Namespace, TaskGroups, etc.).
  2. If using the HTTP API, POST a valid HCL/JSON job body to /v1/jobs instead of an empty or partial body.
  3. Check client-side deserialization: ensure the JSON key ('Job') matches and case-sensitive unmarshaling is not silently dropping it.
  4. Validate the job locally (nomad job validate) before registering to catch malformed specs early.

Example fix

// before
req := &structs.JobRegisterRequest{WriteRequest: w}
srv.RPC("Job.Register", req, &resp)

// after
req := &structs.JobRegisterRequest{Job: job, WriteRequest: w}
srv.RPC("Job.Register", req, &resp)
Defensive patterns

Strategy: validation

Validate before calling

if job == nil || job.ID == "" || len(job.TaskGroups) == 0 {
	return fmt.Errorf("job spec must be non-nil with ID and TaskGroups before registration")
}

Type guard

func isRegisterableJob(j *api.Job) bool {
	return j != nil && j.ID != nil && *j.ID != "" && len(j.TaskGroups) > 0
}

Try / catch

_, _, err := client.Jobs().Register(job, nil)
if err != nil && strings.Contains(err.Error(), "missing job for registration") {
	return fmt.Errorf("request payload did not carry a job object: %w", err)
}

Prevention

When it happens

Trigger: Calling the Job.Register RPC (Register or Revert paths via doRegister) with a JobRegisterRequest whose Job field is nil — e.g. a hand-built RPC request or a malformed API payload that sets namespace/other fields but omits the job spec.

Common situations: Custom tooling or HTTP clients posting to /v1/jobs with an empty/invalid JSON body that deserializes to a nil Job; SDK wrappers that forward a nil job after failed parsing; older clients sending legacy payload shapes.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/5a26821633be8c9b. Report an issue: GitHub.