grpc/grpc-java · error · IllegalArgumentException

rule "name" is absent or empty

Error message

rule "name" is absent or empty

What it means

parseRules iterates the top-level rules of an authorization policy and requires each rule object to have a non-empty "name", used as the policy identifier. A missing or empty name makes the policy ambiguous and translation aborts with IllegalArgumentException.

Source

Thrown at authz/src/main/java/io/grpc/authz/AuthorizationPolicyTranslator.java:132

      Permission.Set.Builder headersSet = Permission.Set.newBuilder();
      for (Map<String, ?> header: headersList) {           
        headersSet.addRules(parseHeader(header));
      }
      andSet.addRules(Permission.newBuilder().setAndRules(headersSet.build()).build());
    }
    if (andSet.getRulesCount() == 0) {
      return Permission.newBuilder().setAny(true).build();
    }
    return Permission.newBuilder().setAndRules(andSet.build()).build();
  }

  private static Map<String, Policy> parseRules(
      List<Map<String, ?>> objects, String name) throws IllegalArgumentException {
    Map<String, Policy> policies = new LinkedHashMap<String, Policy>();
    for (Map<String, ?> object: objects) {
      String policyName = JsonUtil.getString(object, "name");
      if (policyName == null || policyName.isEmpty()) {
        throw new IllegalArgumentException("rule \"name\" is absent or empty");
      }
      List<Principal> principals = new ArrayList<>();
      Map<String, ?> source = JsonUtil.getObject(object, "source");
      if (source != null) {
        principals.add(parseSource(source));
      } else {
        principals.add(Principal.newBuilder().setAny(true).build());
      }
      List<Permission> permissions = new ArrayList<>();
      Map<String, ?> request = JsonUtil.getObject(object, "request");
      if (request != null) {
        permissions.add(parseRequest(request));
      } else {
        permissions.add(Permission.newBuilder().setAny(true).build());
      }
      Policy policy = 
          Policy.newBuilder()
          .addAllPermissions(permissions)

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Add a unique, non-empty "name" to every rule in the policy
  2. Validate the policy JSON before loading (schema or pre-check)
  3. Remove nameless placeholder rules
  4. Deduplicate: also avoid empty-name duplicates after fixing

Example fix

// before
{"rules":[{"source":{"address":"10.0.0.1"},"headers":[{"key":"x-auth","values":["yes"]}]}]}
// after
{"rules":[{"name":"allow-internal","source":{"address":"10.0.0.1"},"headers":[{"key":"x-auth","values":["yes"]}]}]}
Defensive patterns

Strategy: validation

Validate before calling

static void checkRuleName(Map<String, ?> rule) {
  String name = JsonUtil.getString(rule, "name");
  if (name == null || name.isEmpty()) throw new IllegalArgumentException("rule missing \"name\"");
}

Try / catch

try { AuthorizationPolicyTranslator.translate(policyJson, serverName); } catch (IllegalArgumentException e) { throw new PolicyValidationException("Policy rule has no name: " + e.getMessage(), e); }

Prevention

When it happens

Trigger: Authorization policy JSON whose rules array contains an object without "name", e.g. {"source":{...},"headers":[...]} with no name field, or "name": "".

Common situations: Hand-authored policy files; programmatic policy generation that skipped the name field; migrations from formats where names were optional or auto-generated.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/d6066421432367c2. Report an issue: GitHub.