{"record":{"id":"4ca6d5b1770f6035","repo":"didi/DoKit","slug":"unexpected-char-04x-at-d-in-header-name-s","errorCode":null,"errorMessage":"Unexpected char %#04x at %d in header name: %s","messagePattern":"Unexpected char %#04x at (.+?) in header name: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/common/CommonHeaders.java","lineNumber":284,"sourceCode":"\n    /**\n     * Set a field with the specified value. If the field is not found, it is added. If the field is\n     * found, the existing values are replaced.\n     */\n    public Builder set(String name, String value) {\n      checkNameAndValue(name, value);\n      removeAll(name);\n      addLenient(name, value);\n      return this;\n    }\n\n    private void checkNameAndValue(String name, String value) {\n      if (name == null) throw new NullPointerException(\"name == null\");\n      if (name.isEmpty()) throw new IllegalArgumentException(\"name is empty\");\n      for (int i = 0, length = name.length(); i < length; i++) {\n        char c = name.charAt(i);\n        if (c <= '\\u0020' || c >= '\\u007f') {\n          throw new IllegalArgumentException(format(\n              \"Unexpected char %#04x at %d in header name: %s\", (int) c, i, name));\n        }\n      }\n      if (value == null) throw new NullPointerException(\"value == null\");\n      for (int i = 0, length = value.length(); i < length; i++) {\n        char c = value.charAt(i);\n        if ((c <= '\\u001f' && c != '\\t') || c >= '\\u007f') {\n          throw new IllegalArgumentException(format(\n              \"Unexpected char %#04x at %d in %s value: %s\", (int) c, i, name, value));\n        }\n      }\n    }\n\n    /** Equivalent to {@code build().get(name)}, but potentially faster. */\n    public String get(String name) {\n      for (int i = namesAndValues.size() - 2; i >= 0; i -= 2) {\n        if (name.equalsIgnoreCase(namesAndValues.get(i))) {\n          return namesAndValues.get(i + 1);","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/common/CommonHeaders.java#L266-L302","documentation":"Thrown by CommonHeaders.Builder.checkNameAndValue when a header NAME contains a control character (<= U+0020) or a non-ASCII character (>= U+007F) at position i. HTTP/1.x header names must be visible US-ASCII tokens, so okhttp-style validators reject anything outside that range.","triggerScenarios":"builder.add(\"X-Custom Header\", v) (space in name), add(\"X\\tId\", v) (tab), or a name carrying an accented/CJK character, e.g. add(\"版本\", v). The exception message interpolates the offending char's hex code and its index.","commonSituations":"Non-ASCII header names from localization mistakes (using Chinese keys as pseudo-headers); names assembled from unsanitized user input or file content containing tabs/newlines.","solutions":["Restrict header names to visible ASCII tokens: [!#$%&'*+-.^_`|~0-9A-Za-z]","Sanitize before add: name.replaceAll(\"[^\\\\x21-\\\\x7e]\", \"\") or reject and log","If you need arbitrary data, put it in the header VALUE (which allows tabs and is more permissive) with an ASCII name, or URL-encode it"],"exampleFix":"// before\nbuilder.add(\"X-Trace\\tId\", value); // tab in name\n\n// after\nbuilder.add(\"X-Trace-Id\", value);","handlingStrategy":"validation","validationCode":"static boolean isValidHeaderName(String name) {\n  if (name == null || name.isEmpty()) return false;\n  for (int i = 0; i < name.length(); i++) {\n    char c = name.charAt(i);\n    if (c <= ' ' || c >= '\\u007f') return false;\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Restrict header names to ASCII token characters","Never put localized/translated text into header names — use values instead"],"tags":["android","network","headers","validation"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}