grpc/grpc-java · error · IllegalArgumentException
"values" is absent or empty
Error message
"values" is absent or empty
What it means
parseHeader requires each header rule to carry a non-empty "values" list alongside the key. If "values" is missing, null, or an empty list, there is nothing to match against and the translation of the authorization policy fails with IllegalArgumentException.
Source
Thrown at authz/src/main/java/io/grpc/authz/AuthorizationPolicyTranslator.java:86
Authenticated.newBuilder().setPrincipalName(
getStringMatcher(principal)).build()).build());
}
return Principal.newBuilder().setOrIds(principalsSet.build()).build();
}
private static Permission parseHeader(Map<String, ?> header) throws IllegalArgumentException {
String key = JsonUtil.getString(header, "key");
if (key == null || key.isEmpty()) {
throw new IllegalArgumentException("\"key\" is absent or empty");
}
if (key.charAt(0) == ':'
|| key.startsWith("grpc-")
|| UNSUPPORTED_HEADERS.contains(key.toLowerCase(Locale.ROOT))) {
throw new IllegalArgumentException(String.format("Unsupported \"key\" %s", key));
}
List<String> valuesList = JsonUtil.getListOfStrings(header, "values");
if (valuesList == null || valuesList.isEmpty()) {
throw new IllegalArgumentException("\"values\" is absent or empty");
}
Permission.Set.Builder orSet = Permission.Set.newBuilder();
for (String value: valuesList) {
orSet.addRules(
Permission.newBuilder().setHeader(
HeaderMatcher.newBuilder()
.setName(key)
.setStringMatch(getStringMatcher(value)).build()).build());
}
return Permission.newBuilder().setOrRules(orSet.build()).build();
}
private static Permission parseRequest(Map<String, ?> request) throws IllegalArgumentException {
Permission.Set.Builder andSet = Permission.Set.newBuilder();
List<String> pathsList = JsonUtil.getListOfStrings(request, "paths");
if (pathsList != null && !pathsList.isEmpty()) {
Permission.Set.Builder pathsSet = Permission.Set.newBuilder();
for (String path: pathsList) { View on GitHub (pinned to 64daddc1f3)
Solutions
- Add a non-empty "values" array of strings to every headers entry
- Remove rules that genuinely have no values
- Validate the policy schema before translation
- Ensure values are strings, not numbers/objects (getListOfStrings would also fail)
Example fix
// before
{"headers":[{"key":"x-user-group","values":[]}]}
// after
{"headers":[{"key":"x-user-group","values":["admin","editor"]}]} Defensive patterns
Strategy: validation
Validate before calling
static void checkHeaderValues(Map<String, ?> rule) {
List<String> values = JsonUtil.getListOfStrings(rule, "values");
if (values == null || values.isEmpty()) throw new IllegalArgumentException("header rule missing \"values\"");
} Try / catch
try { AuthorizationPolicyTranslator.translate(policyJson, serverName); } catch (IllegalArgumentException e) { throw new PolicyValidationException("Policy header rule has no values: " + e.getMessage(), e); } Prevention
- Always pair "key" with a non-empty "values" array
- Ensure values are strings, not numbers/objects
- Validate policy JSON in CI before deployment
- Remove rules with no meaningful values
When it happens
Trigger: A policy JSON rule has {"key":"x-user-group"} with no "values" array, or "values": [] — including when the JSON writer omitted the field for optional-looking rules.
Common situations: Template-generated policies with unfilled value arrays; rules cloned and values stripped; JSON where values were expected at a different nesting level.
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
- "key" is absent or empty
- rule "name" is absent or empty
- "name" is absent or empty
- "allow_rules" is absent
- Failed to translate authorization policy
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/119477a30366337e.
Report an issue: GitHub.