hashicorp/nomad · error

tasks can only have 1 identity block until all servers are u

Error message

tasks can only have 1 identity block until all servers are upgraded to %s or later

What it means

Workload identity support for multiple identity blocks per task requires every server in the region to run at least minVersionMultiIdentities. Until the whole cluster is upgraded, tasks are limited to a single identity block.

Source

Thrown at nomad/job_endpoint_hooks.go:536

	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)
		}

		for _, t := range tg.Tasks {
			if len(t.Identities) > 1 && !okForIdentity {
				multierror.Append(validationErrors, fmt.Errorf("tasks can only have 1 identity block until all servers are upgraded to %s or later", minVersionMultiIdentities))
			}
			for _, s := range t.Services {
				serviceErrs := v.validateServiceIdentity(
					s, fmt.Sprintf("task %s", t.Name), okForIdentity)
				multierror.Append(validationErrors, serviceErrs)
			}

			vaultWarns, vaultErrs := v.validateVaultIdentity(t, okForIdentity)
			multierror.Append(validationErrors, vaultErrs)
			warnings = append(warnings, vaultWarns...)
		}
	}
	if v.srv.config.JobMaxCount > 0 && totalCount > v.srv.config.JobMaxCount {
		err := fmt.Errorf("total count was greater than configured job_max_count: %d > %d", totalCount, v.srv.config.JobMaxCount)
		multierror.Append(validationErrors, err)
	}

	return warnings, validationErrors.ErrorOrNil()

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Upgrade all servers to the minimum multi-identity version, then resubmit the job
  2. Collapse the task's identities to a single block temporarily
  3. Use legacy vault/consul stanza integration instead of multiple workload identities until upgraded

Example fix

// before
identities: [{name:"vault_x"},{name:"consul_y"}]
// after
identities: [{name:"vault_x"}]  # until servers >= min version
Defensive patterns

Strategy: validation

Validate before calling

for _, tg := range job.TaskGroups {
	for _, t := range tg.Tasks {
		if len(t.Identities) > 1 {
			return fmt.Errorf("task %s uses %d identities; requires multi-identity cluster", t.Name, len(t.Identities))
		}
	}
}

Type guard

func multiIdentitySafe(tasks []*api.Task) bool {
	return !slices.ContainsFunc(tasks, func(t *api.Task) bool { return len(t.Identities) > 1 })
}

Prevention

When it happens

Trigger: Validating/registering a job where any task's identities array has more than one entry while ServersMeetMinimumVersion reports some server below the required version.

Common situations: Mixed-version clusters during rolling upgrades; submitting new-style jobs (multiple WIDs for vault/consul) before finishing server upgrades; staging clusters lagging production versions.

Related errors


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