didi/DoKit · error · IllegalArgumentException

Headers cannot be null

Error message

Headers cannot be null

What it means

Thrown by CommonHeaders.of(String... namesAndValues) when any element of the array is null. The factory trims each entry, so a null name or value would otherwise cause an NPE and cannot be stored in the flat header array.

Source

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

      }
    }
    return null;
  }

  /**
   * Returns headers for the alternating header names and values. There must be an even number of
   * arguments, and they must alternate between header names and values.
   */
  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}.
   */

View on GitHub (pinned to 626827cddb)

Solutions

  1. Substitute empty string (or skip the pair) for absent header values before building the array
  2. Trace which slot is null and fix the producer that left it unset
  3. Prefer the Builder API with explicit add(name, value) calls so every value is visible at the call site

Example fix

// before
CommonHeaders.of("Cookie", cookieHeader); // cookieHeader == null when session absent

// after
CommonHeaders.of("Cookie", cookieHeader == null ? "" : cookieHeader);
Defensive patterns

Strategy: validation

Validate before calling

boolean allNonNull = true;
for (String s : headerArray) { if (s == null) { allNonNull = false; break; } }
if (headerArray != null && headerArray.length % 2 == 0 && allNonNull) { CommonHeaders.of(headerArray); }

Prevention

When it happens

Trigger: Passing an array where one slot was never assigned, e.g. String[] a = new String[4]; a[0]="Host"; a[1]=host; a[2]="Cookie"; a[3] stays null, then CommonHeaders.of(a).

Common situations: Header values computed from nullable request properties (authorization token, session cookie) that are absent when the interceptor runs; arrays sized with new String[n] but only partially filled.

Related errors


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