hashicorp/nomad · error

job can't be submitted with a payload, only dispatched

Error message

job can't be submitted with a payload, only dispatched

What it means

Appended by the job validation hook when a submitted job spec carries a non-empty Payload; payloads are injected only by nomad job dispatch on parameterized jobs and cannot be set on register.

Source

Thrown at nomad/job_endpoint_hooks.go:515

	jobWarnings := job.Warnings()
	if jobWarnings != nil {
		if multi, ok := jobWarnings.(*multierror.Error); ok {
			// Unpack multiple warnings
			warnings = append(warnings, multi.Errors...)
		} else {
			warnings = append(warnings, jobWarnings)
		}
	}

	// TODO: Validate the driver configurations. These had to be removed in 0.9
	//       to support driver plugins, but see issue: #XXXX for more info.

	if job.Type == structs.JobTypeCore {
		multierror.Append(validationErrors, fmt.Errorf("job type cannot be core"))
	}

	if len(job.Payload) != 0 {
		multierror.Append(validationErrors, fmt.Errorf("job can't be submitted with a payload, only dispatched"))
	}

	if job.Priority < structs.JobMinPriority || job.Priority > v.srv.config.JobMaxPriority {
		multierror.Append(validationErrors, fmt.Errorf("job priority must be between [%d, %d]", structs.JobMinPriority, v.srv.config.JobMaxPriority))
	}

	okForIdentity := v.isEligibleForMultiIdentity()

	totalCount := 0
	for _, tg := range job.TaskGroups {
		totalCount += tg.Count

		for _, s := range tg.Services {
			serviceErrs := v.validateServiceIdentity(
				s, fmt.Sprintf("task group %s", tg.Name), okForIdentity)
			multierror.Append(validationErrors, serviceErrs)
		}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Submit a payload-free copy of the job spec; use 'nomad job dispatch <job>' to create runs
  2. Strip the Payload field from the JSON before registering
  3. Register the parameterized job once, then dispatch instances with -meta key=value

Example fix

// before
curl -X POST /v1/jobs -d '{"Job":{"Payload":"aGVsbG8=",...}}'
// after
curl -X POST /v1/jobs -d '{"Job":{...}}'   # register template
nomad job dispatch mybatch                  # submit payload via dispatch
Defensive patterns

Strategy: validation

Validate before calling

if len(job.Payload) != 0 {
	return errors.New("register the template without payload; use dispatch API instead")
}

Type guard

func isDispatchable(job *api.Job) bool { return len(job.Payload) == 0 }

Prevention

When it happens

Trigger: Calling the job register/Validate API with a job whose Payload byte slice is non-empty instead of using the /v1/job/<id>/dispatch endpoint.

Common situations: Registering a parameterized batch job directly instead of dispatching it; restoring exported job specs that captured a dispatched instance's payload.

Related errors


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