{"record":{"id":"21e89f24bfac9ff7","repo":"grpc/grpc-java","slug":"unsupported-key-s","errorCode":null,"errorMessage":"Unsupported \"key\" %s","messagePattern":"Unsupported \"key\" (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"authz/src/main/java/io/grpc/authz/AuthorizationPolicyTranslator.java","lineNumber":82,"sourceCode":"    Principal.Set.Builder principalsSet = Principal.Set.newBuilder();\n    for (String principal: principalsList) {           \n      principalsSet.addIds(\n          Principal.newBuilder().setAuthenticated(\n            Authenticated.newBuilder().setPrincipalName(\n              getStringMatcher(principal)).build()).build());\n    }\n    return Principal.newBuilder().setOrIds(principalsSet.build()).build();\n  }\n\n  private static Permission parseHeader(Map<String, ?> header) throws IllegalArgumentException {\n    String key = JsonUtil.getString(header, \"key\");\n    if (key == null || key.isEmpty()) {\n      throw new IllegalArgumentException(\"\\\"key\\\" is absent or empty\");\n    }\n    if (key.charAt(0) == ':'\n        || key.startsWith(\"grpc-\")\n        || UNSUPPORTED_HEADERS.contains(key.toLowerCase(Locale.ROOT))) {\n      throw new IllegalArgumentException(String.format(\"Unsupported \\\"key\\\" %s\", key));\n    }\n    List<String> valuesList = JsonUtil.getListOfStrings(header, \"values\");\n    if (valuesList == null || valuesList.isEmpty()) {\n      throw new IllegalArgumentException(\"\\\"values\\\" is absent or empty\");\n    }\n    Permission.Set.Builder orSet = Permission.Set.newBuilder();\n    for (String value: valuesList) {\n      orSet.addRules(\n          Permission.newBuilder().setHeader(\n            HeaderMatcher.newBuilder()\n            .setName(key)\n            .setStringMatch(getStringMatcher(value)).build()).build());     \n    }\n    return Permission.newBuilder().setOrRules(orSet.build()).build();\n  }\n\n  private static Permission parseRequest(Map<String, ?> request) throws IllegalArgumentException {\n    Permission.Set.Builder andSet = Permission.Set.newBuilder();","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/authz/src/main/java/io/grpc/authz/AuthorizationPolicyTranslator.java#L64-L100","documentation":"After confirming the header key is present, parseHeader rejects keys that start with ':' (pseudo-headers), start with 'grpc-' (reserved gRPC metadata), or appear in UNSUPPORTED_HEADERS (case-insensitive). These headers cannot be matched by authorization rules, so the translation fails fast.","triggerScenarios":"A policy JSON rule uses a header key like \":path\", \"grpc-timeout\", or another unsupported/reserved header name in its headers list.","commonSituations":"Porting Envoy-style policies that use \":path\" pseudo-headers; rules written against reserved grpc-* metadata; keys differing only in case caught by the lowercase check.","solutions":["Replace the unsupported key with a supported custom header, forwarding that data as application metadata","Remove the offending rule if it targets reserved/internal headers","For \":path\"-style matching, use the policy's supported fields instead of header matchers","Lower-case awareness: rename keys so none normalize into UNSUPPORTED_HEADERS"],"exampleFix":"// before\n{\"headers\":[{\"key\":\":path\",\"values\":[\"/api/*\"]}]}\n// after\n{\"headers\":[{\"key\":\"x-original-path\",\"values\":[\"/api/*\"]}]} // forwarded as a regular header","handlingStrategy":"validation","validationCode":"static final Set<String> UNSUPPORTED = Set.of(\"content-length\", \"content-type\", /* mirror UNSUPPORTED_HEADERS */);\nstatic void checkHeaderKey(String key) {\n  if (key.charAt(0) == ':' || key.startsWith(\"grpc-\") || UNSUPPORTED.contains(key.toLowerCase(Locale.ROOT)))\n    throw new IllegalArgumentException(\"Unsupported header key: \" + key);\n}","typeGuard":null,"tryCatchPattern":"try { AuthorizationPolicyTranslator.translate(policyJson, serverName); } catch (IllegalArgumentException e) { throw new PolicyValidationException(\"Policy uses an unsupported header: \" + e.getMessage(), e); }","preventionTips":["Never use :pseudo-headers or grpc-* metadata in authz rules","Check case-insensitively against reserved header lists","Forward needed data via custom x-* headers","Review Envoy-ported policies for pseudo-header usage"],"tags":["grpc","authz","unsupported-header","policy"],"backgroundTag":"unsupported-config-value","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}