{"record":{"id":"2a063f78cc8828b9","repo":"grpc/grpc-java","slug":"invalid-ascii-characters-in-header-value-for-key","errorCode":null,"errorMessage":"Invalid ASCII characters in header value for key: ","messagePattern":"Invalid ASCII characters in header value for key: ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/internal/grpcservice/HeaderValueValidationUtils.java","lineNumber":50,"sourceCode":"   * Throws {@link IllegalArgumentException} if invalid.\n   */\n  public static void validateHeaderKey(String key) {\n    if (key == null || key.isEmpty() || key.length() > MAX_HEADER_LENGTH) {\n      throw new IllegalArgumentException(\"Invalid header key: \" + key);\n    }\n  }\n\n  /**\n   * Validates that the header value is within allowed length and contains valid ASCII characters.\n   * Throws {@link IllegalArgumentException} if invalid.\n   */\n  public static void validateHeaderValue(String key, String value) {\n    validateHeaderKey(key);\n    if (value == null || value.length() > MAX_HEADER_LENGTH) {\n      throw new IllegalArgumentException(\"Header value length exceeds maximum allowed length\");\n    }\n    if (!key.endsWith(\"-bin\") && !isValidAsciiHeaderValue(value)) {\n      throw new IllegalArgumentException(\n          \"Invalid ASCII characters in header value for key: \" + key);\n    }\n  }\n\n  /**\n   * Validates that the raw header value is within allowed length and contains valid ASCII\n   * characters. Throws {@link IllegalArgumentException} if invalid.\n   */\n  public static void validateHeaderValue(String key, ByteString rawValue) {\n    validateHeaderKey(key);\n    if (rawValue == null || rawValue.size() > MAX_HEADER_LENGTH) {\n      throw new IllegalArgumentException(\"Header value length exceeds maximum allowed length\");\n    }\n    if (!key.endsWith(\"-bin\") && !isValidAsciiHeaderValue(rawValue.toStringUtf8())) {\n      throw new IllegalArgumentException(\n          \"Invalid ASCII characters in header value for key: \" + key);\n    }\n  }","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/internal/grpcservice/HeaderValueValidationUtils.java#L32-L68","documentation":"gRPC-XDS validates that header values contain valid ASCII characters before attaching them to xDS requests. This IllegalArgumentException is thrown when the value contains non-ASCII characters and the header key does not end with '-bin' (binary headers are exempt since they are base64-encoded). It mirrors Envoy's header character validation.","triggerScenarios":"Calling validateHeaderValue(String key, String value) with a value containing non-ASCII bytes (e.g., UTF-8 text, smart quotes, emoji, CJK characters) on a key that does not end with \"-bin\".","commonSituations":"Users putting localized/UTF-8 strings (names, descriptions) into custom headers; config files saved as UTF-8 with BOM or curly quotes; copying values containing non-breaking spaces from docs.","solutions":["Remove or transliterate non-ASCII characters from the header value before validation","Rename the key to end with \"-bin\" and base64-encode the value if binary/UTF-8 data is required","Sanitize the input with a regex filter to strip non-ASCII characters","Wrap the call in try-catch to detect and report invalid header configuration"],"exampleFix":"// before\nHeaderValueValidationUtils.validateHeaderValue(\"x-user-name\", \"José\"); // non-ASCII\n// after\nString sanitized = \"José\".replaceAll(\"[^\\\\x20-\\\\x7E]\", \"\");\nHeaderValueValidationUtils.validateHeaderValue(\"x-user-name\", sanitized);","handlingStrategy":"validation","validationCode":"boolean ok = key.endsWith(\"-bin\") || value.chars().allMatch(c -> c >= 0x20 && c <= 0x7E);\nif (!ok) throw new IllegalArgumentException(\"Non-ASCII in header '\" + key + \"'\");","typeGuard":"static boolean isAsciiSafe(String key, String value) {\n  return key.endsWith(\"-bin\") || value != null && value.chars().allMatch(c -> c >= 0 && c < 128);\n}","tryCatchPattern":"try {\n  HeaderValueValidationUtils.validateHeaderValue(key, value);\n} catch (IllegalArgumentException e) {\n  log.error(\"Header '{}' contains invalid ASCII\", key);\n}","preventionTips":["Sanitize user/locale-derived data before putting it in headers","Use -bin headers + base64 for non-ASCII data","Beware UTF-8 punctuation from config files (smart quotes, BOM)","Unit-test header builders with non-ASCII inputs"],"tags":["grpc","xds","header-validation","ascii"],"backgroundTag":"invalid-argument-format","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"}