hashicorp/nomad · error
cannot compute %q bind name for bind target: %w
Error message
cannot compute %q bind name for bind target: %w
What it means
Binder.Bind wraps any failure from computeBindName with this message, naming the rule's BindType. It means HIL interpolation of the binding rule's BindName template against the identity's claim mappings failed (syntax error, missing variable, or non-string result). Login fails and no token is issued.
Source
Thrown at lib/auth/binder.go:94
rule := raw.(*structs.ACLBindingRule)
if doesSelectorMatch(rule.Selector, identity.Claims) {
matchingRules = append(matchingRules, rule)
vlog.Debug("binding-rule selector matches an identity claim, will evaluate bind-name", "selector", rule.Selector)
} else {
vlog.Debug("bind-rule selector did not match any claims", "selector", rule.Selector)
}
}
if len(matchingRules) == 0 {
return &bindings, nil
}
// Compute role or policy names by interpolating the identity's claim
// mappings into the rule BindName templates.
for _, rule := range matchingRules {
bindName, valid, err := computeBindName(rule.BindType, rule.BindName, identity.ClaimMappings)
switch {
case err != nil:
return nil, fmt.Errorf("cannot compute %q bind name for bind target: %w", rule.BindType, err)
case !valid:
return nil, fmt.Errorf("computed %q bind name for bind target is invalid: %q", rule.BindType, bindName)
}
switch rule.BindType {
case structs.ACLBindingRuleBindTypeRole:
role, err := b.store.GetACLRoleByName(nil, bindName)
if err != nil {
return nil, err
}
if role != nil {
bindings.Roles = append(bindings.Roles, &structs.ACLTokenRoleLink{
ID: role.ID,
})
vlog.Debug("role found with name matching ACL binding-rule", "name", bindName)
} else {
vlog.Debug("no role found with name matching ACL binding-rule", "name", bindName)View on GitHub (pinned to 482b49bf1a)
Solutions
- Check the wrapped inner error (the %w) to see the exact HIL parse/eval failure
- Fix the binding rule's BindName template so all ${var} names match the auth method's ClaimMappings keys
- Verify the IdP actually emits the mapped claims (decode the JWT to inspect claims)
- Test the template with consul/nomad acl binding-rule tooling before applying it
Example fix
// before: bind name references missing claim
BindName: "${dept}-team"
// after: align with ClaimMappings key "department"
BindName: "${department}-team" Defensive patterns
Strategy: validation
Validate before calling
// pre-validate bind name template variables against claim mappings
func validateBindNameTemplate(tmpl string, claims map[string]string) error {
for _, m := range hilVarPattern.FindAllStringSubmatch(tmpl, -1) {
if _, ok := claims[m[1]]; !ok {
return fmt.Errorf("template var %q not in claim mappings", m[1])
}
}
return nil
}
var hilVarPattern = regexp.MustCompile(`\$\{([^}]+)\}`) Try / catch
if _, err := binder.Bind(log, am, identity); err != nil {
var bindErr error
if strings.Contains(err.Error(), "cannot compute") { bindErr = ErrBadBindTemplate }
return fmt.Errorf("login rejected: %w", err)
} Prevention
- Keep BindName templates limited to literal text plus ${claim} keys that exist in ClaimMappings
- Add a CI check that every ${var} in binding rules has a matching ClaimMappings entry
- Test binding rules with a sample token before production rollout
When it happens
Trigger: Calling Login (or Bind) for an auth method whose matching ACL binding rule has a BindName containing invalid HIL syntax or referencing a claim mapping variable not present in identity.ClaimMappings.
Common situations: Typo in a ${claim} variable name in the bind name template; template references a claim the IdP never emits; malformed HIL like unclosed ${; auth method's ClaimMappings changed while binding rules still reference old keys.
Related errors
- computed %q bind name for bind target is invalid: %q
- unknown binding rule bind type: %s
- generated unexpected hil type: %s
- no signed workload identity available
- JWT login returned an empty secret
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/980e22270e636aad.
Report an issue: GitHub.