elastic/elasticsearch · error · IllegalArgumentException
[{}] doesn't support arrays. Use a single object with multip
Error message
[{}] doesn't support arrays. Use a single object with multiple fields. What it means
Thrown when declareNamedObjects is invoked with the 3-argument overload (no ordered-mode callback), and the parser then encounters a JSON array at the field position. Named objects in this library must be represented as a JSON object whose keys are the object names; the default ordered-mode callback rejects arrays because it has no way to assign names to array elements.
Source
Thrown at libs/x-content/src/main/java/org/elasticsearch/xcontent/ObjectParser.java:568
);
}
private static XContentParseException wrapParseError(ParseField field, XContentParser p, IOException e, String s) {
return new XContentParseException(p.getTokenLocation(), "[" + field + "] " + s, e);
}
private static XContentParseException rethrowFieldParseFailure(ParseField field, XContentParser p, String currentName, Exception e) {
return new XContentParseException(p.getTokenLocation(), "[" + field + "] failed to parse field [" + currentName + "]", e);
}
@Override
public <T> void declareNamedObjects(
BiConsumer<Value, List<T>> consumer,
NamedObjectParser<T, Context> namedObjectParser,
ParseField field
) {
Consumer<Value> orderedModeCallback = (v) -> {
throw new IllegalArgumentException("[" + field + "] doesn't support arrays. Use a single object with multiple fields.");
};
declareNamedObjects(consumer, namedObjectParser, orderedModeCallback, field);
}
/**
* Functional interface for instantiating and parsing named objects. See ObjectParserTests#NamedObject for the canonical way to
* implement this for objects that themselves have a parser.
*/
@FunctionalInterface
public interface NamedObjectParser<T, Context> {
T parse(XContentParser p, Context c, String name) throws IOException;
}
/**
* Get the name of the parser.
*/
@Override
public String getName() {View on GitHub (pinned to db6a809a66)
Solutions
- Change the JSON array to an object whose keys are the named-object identifiers.
- If the endpoint truly supports arrays, ensure the server-side parser uses the 4-argument declareNamedObjects with an ordered-mode callback.
- Update the client serializer to produce a keyed object for this field.
Example fix
// before — array of named objects (rejected)
{
"aggregations": [
{ "name": "agg1", "type": "terms" }
]
}
// after — object with named keys
{
"aggregations": {
"agg1": { "terms": { "field": "cat" } }
}
} Defensive patterns
Strategy: validation
Validate before calling
// Before sending, verify named-object fields are objects not arrays
public static void ensureNamedObjectsAreMaps(String json) throws Exception {
JsonNode root = new ObjectMapper().readTree(json);
for (String field : namedObjectFields) {
if (root.has(field) && root.get(field).isArray()) {
throw new IllegalArgumentException(field + " must be an object, not an array");
}
}
} Try / catch
try {
objectParser.parse(parser, context);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("doesn't support arrays")) {
return badRequest(e.getMessage());
}
throw e;
} Prevention
- Serialize named-object collections as keyed maps in client code, not as arrays.
- Review the API spec for each field: object-keyed vs array-ordered.
- If the endpoint supports arrays, ensure the server uses the 4-arg declareNamedObjects.
When it happens
Trigger: Sending a JSON array for a field whose ObjectParser was declared with the 3-argument declareNamedObjects (unordered mode). For example, an API that expects {"name1": {...}, "name2": {...}} but receives [{...}, {...}].
Common situations: Client library serializing a list as a JSON array when the server expects a map. Copying an array-based format from one API into another that uses object-based named objects. Misreading the API docs and assuming arrays are accepted.
Related errors
- [{}] Expected START_OBJECT but was: {}
- Required one of fields {}, but none were specified.
- The following fields are not allowed together: {}
- [{}] failed to parse object
- [{}] failed to parse field [{}]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/8e2fc4e2cbfe80ca.
Report an issue: GitHub.