hashicorp/nomad · error

Task %s cannot have an identity for Vault until all servers

Error message

Task %s cannot have an identity for Vault until all servers are upgraded to %s or later

What it means

During job validation, Nomad checks whether a task defines a Workload Identity for Vault. If the task has a Vault identity but the cluster is not yet guaranteed to run servers at minVersionMultiIdentities (the version introducing multi-identities), registration is rejected because older servers cannot handle the identity. This protects mixed-version clusters from jobs that depend on features older servers cannot serve.

Source

Thrown at nomad/job_endpoint_hooks.go:599

// inject task identities if necessary.
func (v *jobValidate) validateVaultIdentity(t *structs.Task, okForIdentity bool) ([]error, error) {
	var warnings []error

	if t.Vault == nil {
		// Warn if task doesn't use Vault but has Vault identities.
		for _, wid := range t.Identities {
			if strings.HasPrefix(wid.Name, structs.WorkloadIdentityVaultPrefix) {
				warnings = append(warnings, fmt.Errorf("Task %s has an identity called %s but no vault block", t.Name, wid.Name))
			}
		}
		return warnings, nil
	}

	vaultWIDName := t.Vault.IdentityName()
	vaultWID := t.GetIdentity(vaultWIDName)

	if vaultWID != nil && !okForIdentity {
		return warnings, fmt.Errorf("Task %s cannot have an identity for Vault until all servers are upgraded to %s or later", t.Name, minVersionMultiIdentities)
	}

	if vaultWID == nil {
		// Tasks using non-default clusters are required to have an identity.
		if t.Vault.Cluster != structs.VaultDefaultCluster {
			return warnings, fmt.Errorf(
				"Task %s uses Vault cluster %s but does not have an identity named %s and no default identity is provided in agent configuration",
				t.Name, t.Vault.Cluster, vaultWIDName,
			)
		}

		return warnings, nil
	}

	return warnings, nil
}

type memoryOversubscriptionValidate struct {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Upgrade all server agents to minVersionMultiIdentities or later before deploying jobs with Vault identities
  2. Remove the Vault identity from the task (or downgrade the job spec to use Vault policy blocks) until the upgrade completes
  3. Set the identity only on tasks in clusters verified to be at the required version

Example fix

// before
task { identities: [{ name: "vault_default", ... }] }
// after
// upgrade all servers >= minVersionMultiIdentities, or remove the identity until then
 task { vault { policies: ["read"] } }
Defensive patterns

Strategy: validation

Validate before calling

// before submit
if task.Identities != nil {
  for _, id := range task.Identities {
    if strings.HasPrefix(id.Name, "vault_") {
      ver := serverVersion() // query /v1/agent/health or members
      if compareSemver(ver, minVersionMultiIdentities) < 0 {
        return fmt.Errorf("server %s too old for vault identities", ver)
      }
    }
  }
}

Prevention

When it happens

Trigger: Registering or updating a job whose task sets an identity whose name matches t.Vault.IdentityName() (i.e. a Vault workload identity) while the server cluster is not okForIdentity (servers below minVersionMultiIdentities). Raised from validateVaultIdentity via jobendpoint Validate.

Common situations: Operator upgrades Nomad partially; a user writes jobs using the new Vault identity syntax (native workload identities instead of Vault token policies) before every server is upgraded; automation templating new job specs onto an older cluster.

Related errors


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