{"record":{"id":"980e22270e636aad","repo":"hashicorp/nomad","slug":"cannot-compute-q-bind-name-for-bind-target-w","errorCode":null,"errorMessage":"cannot compute %q bind name for bind target: %w","messagePattern":"cannot compute %q bind name for bind target: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/auth/binder.go","lineNumber":94,"sourceCode":"\t\trule := raw.(*structs.ACLBindingRule)\n\t\tif doesSelectorMatch(rule.Selector, identity.Claims) {\n\t\t\tmatchingRules = append(matchingRules, rule)\n\t\t\tvlog.Debug(\"binding-rule selector matches an identity claim, will evaluate bind-name\", \"selector\", rule.Selector)\n\t\t} else {\n\t\t\tvlog.Debug(\"bind-rule selector did not match any claims\", \"selector\", rule.Selector)\n\t\t}\n\t}\n\tif len(matchingRules) == 0 {\n\t\treturn &bindings, nil\n\t}\n\n\t// Compute role or policy names by interpolating the identity's claim\n\t// mappings into the rule BindName templates.\n\tfor _, rule := range matchingRules {\n\t\tbindName, valid, err := computeBindName(rule.BindType, rule.BindName, identity.ClaimMappings)\n\t\tswitch {\n\t\tcase err != nil:\n\t\t\treturn nil, fmt.Errorf(\"cannot compute %q bind name for bind target: %w\", rule.BindType, err)\n\t\tcase !valid:\n\t\t\treturn nil, fmt.Errorf(\"computed %q bind name for bind target is invalid: %q\", rule.BindType, bindName)\n\t\t}\n\n\t\tswitch rule.BindType {\n\t\tcase structs.ACLBindingRuleBindTypeRole:\n\t\t\trole, err := b.store.GetACLRoleByName(nil, bindName)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tif role != nil {\n\t\t\t\tbindings.Roles = append(bindings.Roles, &structs.ACLTokenRoleLink{\n\t\t\t\t\tID: role.ID,\n\t\t\t\t})\n\t\t\t\tvlog.Debug(\"role found with name matching ACL binding-rule\", \"name\", bindName)\n\t\t\t} else {\n\t\t\t\tvlog.Debug(\"no role found with name matching ACL binding-rule\", \"name\", bindName)","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/lib/auth/binder.go#L76-L112","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: bind name references missing claim\nBindName: \"${dept}-team\"\n// after: align with ClaimMappings key \"department\"\nBindName: \"${department}-team\"","handlingStrategy":"validation","validationCode":"// pre-validate bind name template variables against claim mappings\nfunc validateBindNameTemplate(tmpl string, claims map[string]string) error {\n    for _, m := range hilVarPattern.FindAllStringSubmatch(tmpl, -1) {\n        if _, ok := claims[m[1]]; !ok {\n            return fmt.Errorf(\"template var %q not in claim mappings\", m[1])\n        }\n    }\n    return nil\n}\nvar hilVarPattern = regexp.MustCompile(`\\$\\{([^}]+)\\}`)","typeGuard":null,"tryCatchPattern":"if _, err := binder.Bind(log, am, identity); err != nil {\n    var bindErr error\n    if strings.Contains(err.Error(), \"cannot compute\") { bindErr = ErrBadBindTemplate }\n    return fmt.Errorf(\"login rejected: %w\", err)\n}","preventionTips":["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"],"tags":["auth","acl-binding-rule","template-interpolation"],"backgroundTag":"bind-name-interpolation-failed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}