didi/DoKit · error · IllegalArgumentException

Unexpected header: " + name + ": " + value

Error message

Unexpected header: " + name + ": " + value

What it means

Thrown by CommonHeaders.of(String... namesAndValues) during the malformed-header check: after trimming, a header name is empty or the name or value contains a NUL character ('\0'). Both conditions would produce unparseable or unsafe header output, mirroring okhttp's Headers validation.

Source

Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/common/CommonHeaders.java:178

  public static CommonHeaders of(String... namesAndValues) {
    if (namesAndValues == null) throw new NullPointerException("namesAndValues == null");
    if (namesAndValues.length % 2 != 0) {
      throw new IllegalArgumentException("Expected alternating header names and values");
    }

    // Make a defensive copy and clean it up.
    namesAndValues = namesAndValues.clone();
    for (int i = 0; i < namesAndValues.length; i++) {
      if (namesAndValues[i] == null) throw new IllegalArgumentException("Headers cannot be null");
      namesAndValues[i] = namesAndValues[i].trim();
    }

    // Check for malformed headers.
    for (int i = 0; i < namesAndValues.length; i += 2) {
      String name = namesAndValues[i];
      String value = namesAndValues[i + 1];
      if (name.length() == 0 || name.indexOf('\0') != -1 || value.indexOf('\0') != -1) {
        throw new IllegalArgumentException("Unexpected header: " + name + ": " + value);
      }
    }

    return new CommonHeaders(namesAndValues);
  }

  /**
   * Returns headers for the header names and values in the {@link Map}.
   */
  public static CommonHeaders of(Map<String, String> headers) {
    if (headers == null) throw new NullPointerException("headers == null");

    // Make a defensive copy and clean it up.
    String[] namesAndValues = new String[headers.size() * 2];
    int i = 0;
    for (Map.Entry<String, String> header : headers.entrySet()) {
      if (header.getKey() == null || header.getValue() == null) {
        throw new IllegalArgumentException("Headers cannot be null");

View on GitHub (pinned to 626827cddb)

Solutions

  1. Log the offending pair before calling of() so you can see exactly which header is empty or contains '\0'
  2. Filter out blank names and sanitize values (strip NUL bytes) before constructing the array
  3. Fix the upstream parser that produced an empty name — typically a missing indexOf(':') guard when splitting a header line

Example fix

// before
CommonHeaders.of(parsedName, parsedValue); // parsedName == "" for lines like ": value"

// after
if (parsedName != null && !parsedName.trim().isEmpty() && parsedName.indexOf('\0') == -1 && parsedValue.indexOf('\0') == -1) {
  builder.add(parsedName.trim(), parsedValue.trim());
}
Defensive patterns

Strategy: validation

Validate before calling

static boolean isValidHeaderPair(String n, String v) {
  n = n == null ? "" : n.trim();
  v = v == null ? "" : v.trim();
  return n.length() > 0 && n.indexOf('\0') == -1 && v.indexOf('\0') == -1;
}

Prevention

When it happens

Trigger: Passing a pair like ("", "gzip") or a header value containing '\0' (often from binary data accidentally coerced into a String, or from trimming a string that was all whitespace leaving an empty name).

Common situations: Parsing raw header lines into pairs and losing the name when the line has no colon; a header name that consists only of spaces (trim → empty); binary/null-byte payload contamination in mock or replayed network data.

Related errors


AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14). Data as JSON: /api/errors/654ee4ecb21e983c. Report an issue: GitHub.