grpc/grpc-go · error

%d: "name" is not present

Error message

%d: "name" is not present

What it means

Raised by parseRules in the gRPC authz SDK policy translator while iterating the rules array of an allow_rules or deny_rules block. Every rule in the gRPC authorization-policy JSON schema MUST have a non-empty "name" (used as the RBAC policy key, prefixed with the policy name). The %d is the zero-based rule index, telling you exactly which array element is missing its name.

Source

Thrown at authz/rbac_translator.go:274

			return nil, err
		}
		and = append(and, permissionAnd(headers))
	}
	if len(and) > 0 {
		return permissionAnd(and), nil
	}
	return &v3rbacpb.Permission{
		Rule: &v3rbacpb.Permission_Any{
			Any: true,
		},
	}, nil
}

func parseRules(rules []rule, prefixName string) (map[string]*v3rbacpb.Policy, error) {
	policies := make(map[string]*v3rbacpb.Policy)
	for i, rule := range rules {
		if rule.Name == "" {
			return policies, fmt.Errorf(`%d: "name" is not present`, i)
		}
		permission, err := parseRequest(rule.Request)
		if err != nil {
			return nil, fmt.Errorf("%d: %v", i, err)
		}
		policyName := prefixName + "_" + rule.Name
		policies[policyName] = &v3rbacpb.Policy{
			Principals:  []*v3rbacpb.Principal{parsePeer(rule.Source)},
			Permissions: []*v3rbacpb.Permission{permission},
		}
	}
	return policies, nil
}

// Parse auditLoggingOptions to the associated RBAC protos. The single
// auditLoggingOptions results in two different parsed protos, one for the allow
// policy and one for the deny policy
func (options *auditLoggingOptions) toProtos() (allow *v3rbacpb.RBAC_AuditLoggingOptions, deny *v3rbacpb.RBAC_AuditLoggingOptions, err error) {

View on GitHub (pinned to 03255a9237)

Solutions

  1. Open the policy JSON, go to the index reported by %d in the error, and add a unique non-empty "name" to that rule object.
  2. Ensure every rule name is unique within its rules array (names become RBAC policy keys prefixed by the top-level policy name).
  3. Validate the JSON against the gRPC authorization policy JSON schema before passing it to NewStaticInterceptors.
  4. Use json.Unmarshal into the SDK's policy struct in a unit test to catch missing names before deploy.

Example fix

// before:
{
  "name": "example",
  "allow_rules": [
    { "request": { "paths": ["/foo"] } }   // missing "name"
  ]
}

// after:
{
  "name": "example",
  "allow_rules": [
    { "name": "allow-foo", "request": { "paths": ["/foo"] } }
  ]
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate every rule in allow_rules/deny_rules has a non-empty unique name
// before passing the policy to authz.NewStaticInterceptors.
type sdkRule struct {
    Name    string          `json:"name"`
    Request json.RawMessage `json:"request"`
}
type sdkPolicy struct {
    Name       string    `json:"name"`
    AllowRules []sdkRule `json:"allow_rules"`
    DenyRules  []sdkRule `json:"deny_rules"`
}
func validateRuleNames(policyStr string) error {
    var p sdkPolicy
    if err := json.Unmarshal([]byte(policyStr), &p); err != nil {
        return err
    }
    check := func(rules []sdkRule, group string) error {
        seen := map[string]bool{}
        for i, r := range rules {
            if r.Name == "" {
                return fmt.Errorf("%s[%d]: missing \"name\"", group, i)
            }
            if seen[r.Name] {
                return fmt.Errorf("%s[%d]: duplicate name %q", group, i, r.Name)
            }
            seen[r.Name] = true
        }
        return nil
    }
    if err := check(p.AllowRules, "allow_rules"); err != nil { return err }
    return check(p.DenyRules, "deny_rules")
}

Prevention

When it happens

Trigger: Calling authz.NewStaticInterceptors (or feeding a JSON policy string into translatePolicy) where an entry in allow_rules[] or deny_rules[] has no "name" field, or sets it to "". parseRules checks `rule.Name == ""` at index i and returns this error.

Common situations: Hand-writing the authorization policy JSON and forgetting the name key on one rule; generating the policy from a template that omits name; renaming the field in an earlier edit and leaving a blank string; assuming name is optional like in some Envoy RBAC configs.

Related errors


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/9c7180e52cf3a160. Report an issue: GitHub.