hashicorp/nomad · error

Job type %q does not allow update block

Error message

Job type %q does not allow update block

What it means

Nomad's job validation (Job.Validate / TaskGroup.Validate in nomad/structs/structs.go) rejects an `update` block on a job whose type is neither "service" nor "system". Rolling-update/deployment strategy semantics only make sense for long-running job types, so batch, sysbatch, or custom-typed jobs carrying an `update` stanza are invalid. The message is appended to a multierror and surfaced with the rest of the job validation failures.

Source

Thrown at nomad/structs/structs.go:7227

		} else {
			mErr = multierror.Append(mErr, fmt.Errorf("Task Group %v should have a reschedule policy", tg.Name))
		}
	}

	if tg.EphemeralDisk != nil {
		if err := tg.EphemeralDisk.Validate(); err != nil {
			mErr = multierror.Append(mErr, err)
		}
	} else {
		mErr = multierror.Append(mErr, fmt.Errorf("Task Group %v should have an ephemeral disk object", tg.Name))
	}

	// Validate the update strategy
	if u := tg.Update; u != nil {
		switch j.Type {
		case JobTypeService, JobTypeSystem:
		default:
			mErr = multierror.Append(mErr, fmt.Errorf("Job type %q does not allow update block", j.Type))
		}
		if err := u.Validate(); err != nil {
			mErr = multierror.Append(mErr, err)
		}
	}

	// Validate the migration strategy
	switch j.Type {
	case JobTypeService:
		if tg.Migrate != nil {
			if err := tg.Migrate.Validate(); err != nil {
				mErr = multierror.Append(mErr, err)
			}
		}
	default:
		if tg.Migrate != nil {
			mErr = multierror.Append(mErr, fmt.Errorf("Job type %q does not allow migrate block", j.Type))
		}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Remove the `update` block from the task group in the job spec.
  2. Or change the job's `type` to "service" if rolling updates are actually intended.
  3. For batch jobs needing reschedule-like behavior, use `restart` and `reschedule` stanzas appropriate to the type instead.

Example fix

// before
type = "batch"
update {
  max_parallel = 1
}
// after
type = "batch"
# update block removed (not allowed for batch jobs)
Defensive patterns

Strategy: validation

Validate before calling

// Go: pre-validate before submitting
if job.Type != structs.JobTypeService && job.Type != structs.JobTypeSystem {
  for _, tg := range job.TaskGroups {
    if tg.Update != nil {
      return fmt.Errorf("group %q: update block not allowed for job type %q", tg.Name, job.Type)
    }
  }
}

Prevention

When it happens

Trigger: Submitting (via jobs API/CLI `nomad job run`) a job spec where the `update` stanza is present in a task group but `job type = "batch"`, `"sysbatch"`, or any non-service/system type.

Common situations: Copying an update stanza from an existing service job into a batch job template; switching a job's type from service to batch after adding deployment automation; tooling that always emits an update block.

Related errors


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