hashicorp/nomad · error

Service %s in %s has an identity with an empty name

Error message

Service %s in %s has an identity with an empty name

What it means

Fires in validateServiceIdentity when a service's identity block has an empty name; workload identities require a concrete identity name to derive the token path and variables.

Source

Thrown at nomad/job_endpoint_hooks.go:571

	return warnings, validationErrors.ErrorOrNil()
}

func (v *jobValidate) isEligibleForMultiIdentity() bool {
	if v.srv == nil || v.srv.serf == nil {
		return true // handle tests w/o real servers safely
	}
	return v.srv.peersCache.ServersMeetMinimumVersion(
		v.srv.Region(), minVersionMultiIdentities, true)
}

func (v *jobValidate) validateServiceIdentity(s *structs.Service, parent string, okForIdentity bool) error {
	if s.Identity != nil && !okForIdentity {
		return fmt.Errorf("Service %s in %s cannot have an identity until all servers are upgraded to %s or later",
			s.Name, parent, minVersionMultiIdentities)
	}
	if s.Identity != nil && s.Identity.Name == "" {
		return fmt.Errorf("Service %s in %s has an identity with an empty name", s.Name, parent)
	}

	return nil
}

// validateVaultIdentity validates that a task is properly configured to access
// a Vault cluster.
//
// It assumes the jobImplicitIdentitiesHook mutator hook has been called to
// 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))

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set identity.name explicitly, e.g. identity { name = "consul-service-<service>" }
  2. Remove the empty identity block if service identities are not actually needed

Example fix

// before
service { name = "web" identity { } }
// after
service { name = "web" identity { name = "consul-service-web" } }
Defensive patterns

Strategy: validation

Validate before calling

for _, svc := range group.Services {
	if svc.Identity != nil && svc.Identity.Name == "" {
		return fmt.Errorf("service %s identity.name required", svc.Name)
	}
}

Type guard

func identityNamed(w *api.WorkloadIdentity) bool { return w != nil && w.Name != "" }

Prevention

When it happens

Trigger: Submitting a job with a service whose identity is non-nil but whose identity.name is the empty string.

Common situations: Half-converted job specs where identity {} was added but name left blank; templating that renders an empty name variable; hand-written HCL missing the required attribute.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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