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
- Submit a payload-free copy of the job spec; use 'nomad job dispatch <job>' to create runs
- Strip the Payload field from the JSON before registering
- 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
- Use nomad job dispatch for parameterized jobs, never direct register
- Strip Payload when exporting/restoring job specs
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
- 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
- Job ID contains a space
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/ee29ec05e4bb4e37.
Report an issue: GitHub.