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

  1. Change the JSON array to an object whose keys are the named-object identifiers.
  2. If the endpoint truly supports arrays, ensure the server-side parser uses the 4-argument declareNamedObjects with an ordered-mode callback.
  3. 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

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


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/8e2fc4e2cbfe80ca. Report an issue: GitHub.