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

  1. Check the wrapped inner error (the %w) to see the exact HIL parse/eval failure
  2. Fix the binding rule's BindName template so all ${var} names match the auth method's ClaimMappings keys
  3. Verify the IdP actually emits the mapped claims (decode the JWT to inspect claims)
  4. 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

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


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