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
- Add `aud = ["consul.io"]` (or the intended audiences) inside the identity block.
- Remove the identity block entirely if workload identity is not needed.
- 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
- Always include `aud = ["consul.io"]` (or target audiences) in identity blocks
- Check templating so aud lists are not dropped during variable expansion
- Keep identity definitions in shared snippets that include audiences
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
- an empty string is an invalid audience (%d)
- no signed workload identity available
- JWT auth method requires either OIDCDiscoveryURL, or JWKS UR
- missing Audience
- PrivateKey is required for `private_key` KeySource
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/0425f60de783c9ed.
Report an issue: GitHub.