hashicorp/nomad · error

Service identity must provide at least one target aud value

Error message

Service identity must provide at least one target aud value

What it means

validateIdentity requires that a service's identity block (workload identity for Consul / Vault JWT audience) lists at least one audience value. The identity is used to mint a JWT with `aud` claims; an empty audience list produces a useless token, so validation rejects it.

Source

Thrown at nomad/structs/services.go:936

			mErr.Errors = append(mErr.Errors, err)
		}
	}

	// Services using the Nomad provider do not support Consul connect.
	if s.Connect != nil {
		mErr.Errors = append(mErr.Errors, errors.New("Service with provider nomad cannot include Connect blocks"))
	}
}

// validateIdentity performs validation on workload identity field populated by
// the job mutating hook
func (s *Service) validateIdentity() error {
	if s.Identity == nil {
		return nil
	}

	if len(s.Identity.Audience) == 0 {
		return fmt.Errorf("Service identity must provide at least one target aud value")
	}

	return nil
}

// ValidateName checks if the service Name is valid and should be called after
// the name has been interpolated
func (s *Service) ValidateName(name string) error {
	// Ensure the service name is valid per RFC-952 §1
	// (https://tools.ietf.org/html/rfc952), RFC-1123 §2.1
	// (https://tools.ietf.org/html/rfc1123), and RFC-2782
	// (https://tools.ietf.org/html/rfc2782).
	//  This validation is enforced on Nomad, but not on Consul, however if
	//  consul-template is being used, service names with dots in them wont be
	//  admissible.
	re := regexp.MustCompile(`^(?i:[a-z0-9]|[a-z0-9][a-z0-9\-]{0,61}[a-z0-9])$`)
	if !re.MatchString(name) {
		return fmt.Errorf("Service name must be valid per RFC 1123 and can contain only alphanumeric characters or dashes and must be no longer than 63 characters")

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Add `aud = ["consul.io"]` (or the intended audiences) inside the identity block.
  2. Remove the identity block entirely if workload identity is not needed.
  3. Check templating/HCL merging so the aud list is not dropped by variable expansion.

Example fix

// before
service {
  name = "web"
  identity {
    name = "web_identity"
  }
}
// after
service {
  name = "web"
  identity {
    name = "web_identity"
    aud = ["consul.io"]
  }
}
Defensive patterns

Strategy: validation

Validate before calling

if id := svc.Identity; id != nil && len(id.Audience) == 0 {
  return fmt.Errorf("identity %q must declare at least one aud", id.Name)
}

Prevention

When it happens

Trigger: A service stanza with `identity { name = "..." }` but no `aud = [...]` array.

Common situations: Omitting the aud array when configuring Consul workload identities; templating the identity block where the audience list variable is empty.

Related errors


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