alibaba/nacos · error · IllegalArgumentException
list size must be a multiple of 2
Error message
list size must be a multiple of 2
What it means
Thrown by Header.addAll(List<String>) when the supplied KV list has an odd number of entries. The method treats the list as flat key/value pairs (odd index = key, even index = value), so an odd size leaves a dangling key with no value and the contract is violated. It is an IllegalArgumentException raised before any entry is put into the header map.
Source
Thrown at common/src/main/java/com/alibaba/nacos/common/http/param/Header.java:113
List<String> list = new ArrayList<>(header.size() * 2);
Iterator<Map.Entry<String, String>> iterator = iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
list.add(entry.getKey());
list.add(entry.getValue());
}
return list;
}
/**
* Add all KV list to header. The odd index is key and the even index is value.
*
* @param list KV list
* @return header
*/
public Header addAll(List<String> list) {
if ((list.size() & 1) != 0) {
throw new IllegalArgumentException("list size must be a multiple of 2");
}
for (int i = 0; i < list.size();) {
String key = list.get(i++);
if (StringUtils.isNotEmpty(key)) {
header.put(key, list.get(i++));
}
}
return this;
}
/**
* Add all parameters to header.
*
* @param params parameters
*/
public void addAll(Map<String, String> params) {
if (MapUtil.isNotEmpty(params)) {
for (Map.Entry<String, String> entry : params.entrySet()) {View on GitHub (pinned to 9b989acdf1)
Solutions
- Ensure the list length is even before calling addAll: assert (list.size() & 1) == 0, or guard with an if.
- Build the list from an explicit Map.entrySet() loop that always writes both key and value, so a pair can never be split.
- Prefer header.addAll(Map<String,String>) (the map overload in the same class) over the flat List form to make pairing structural.
- If the list is user supplied, log list.size() and the offending tail before rejecting so the caller sees the unpaired key.
Example fix
// before
List<String> flat = new ArrayList<>();
headers.forEach((k,v) -> { flat.add(k); /* v conditionally skipped */ });
header.addAll(flat); // throws if any value omitted
// after
Map<String,String> safe = new LinkedHashMap<>();
headers.forEach((k,v) -> { if (k != null && v != null) safe.put(k, v); });
header.addAll(safe); Defensive patterns
Strategy: validation
Validate before calling
if (list == null || (list.size() & 1) != 0) {
throw new IllegalArgumentException("header KV list must have even size, got " + (list == null ? 0 : list.size()));
}
header.addAll(list); Type guard
boolean isEvenKvList(List<String> list) {
return list != null && (list.size() & 1) == 0;
} Prevention
- Prefer the Map<String,String> overload of addAll over the flat List form.
- When flattening a Map, always write both key and value in the same iteration.
- Add a unit test asserting addAll rejects odd-sized lists and accepts even ones.
When it happens
Trigger: Calling Header.newInstance().addAll(list) or header.addAll(Arrays.asList("k1","v1","k2")) where list.size() is odd; building a Header from a flattened collection produced by splitting or streaming without ensuring pairs.
Common situations: Manually flattening a Map into an alternating key/value List and dropping the last value; passing a varargs/collection whose last element was filtered out; off-by-one when zipping headers from an HTTP response into a flat list.
Related errors
- MediaType must not be empty
- Unsupported http method : {name}
- httpClientFactory is null
- Illegal url path expression : {subPath}
- 20002
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/0f397f364e0a02a2.
Report an issue: GitHub.