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
- Log the offending pair before calling of() so you can see exactly which header is empty or contains '\0'
- Filter out blank names and sanitize values (strip NUL bytes) before constructing the array
- 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
- Validate names/values (non-empty after trim, no NUL) before building the array
- Guard header-line parsers with a colon check so empty names never reach of()
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
- Expected alternating header names and values
- Unexpected char %#04x at %d in header name: %s
- Unexpected char %#04x at %d in %s value: %s
- namesAndValues == null
- Headers cannot be null
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/654ee4ecb21e983c.
Report an issue: GitHub.