elastic/elasticsearch · error · IllegalArgumentException
Required [{fields}]
Error message
Required [{fields}] What it means
After all fields are consumed, ConstructingObjectParser checks each constructor argument slot; any slot still null for a required (non-optional) constructorArg is collected into a comma-separated list and reported. The message enumerates every missing required argument in declaration order. Optional constructor args (optionalConstructorArg) do not trigger this; only required constructorArg() slots do.
Source
Thrown at libs/x-content/src/main/java/org/elasticsearch/xcontent/ConstructingObjectParser.java:556
/*
* The object hasn't been built which ought to mean we're missing some constructor arguments. But they could be optional! We'll
* check if they are all optional and build the error message at the same time - if we don't start the error message then they
* were all optional!
*/
StringBuilder message = null;
for (int i = 0; i < constructorArgs.length; i++) {
if (constructorArgs[i] != null) continue;
ConstructorArgInfo arg = constructorArgInfos.get(parser.getRestApiVersion()).get(i);
if (false == arg.required) continue;
if (message == null) {
message = new StringBuilder("Required [").append(arg.field);
} else {
message.append(", ").append(arg.field);
}
}
if (message != null) {
// There were non-optional constructor arguments missing.
throw new IllegalArgumentException(message.append(']').toString());
}
/*
* If there weren't any constructor arguments declared at all then we won't get an error message but this isn't really a valid
* use of ConstructingObjectParser. You should be using ObjectParser instead. Since this is more of a programmer error and the
* parser ought to still work we just assert this.
*/
assert false == constructorArgInfos.isEmpty()
: "["
+ objectParser.getName()
+ "] must configure at least one constructor "
+ "argument. If it doesn't have any it should use ObjectParser instead of ConstructingObjectParser. This is a bug "
+ "in the parser declaration.";
// All missing constructor arguments were optional. Just build the target and return it.
buildTarget();
return targetObject;
}
private void buildTarget() {View on GitHub (pinned to db6a809a66)
Solutions
- Add the missing field(s) named in the message to the input object.
- If the field is genuinely optional at your call site, declare it with optionalConstructorArg() instead of constructorArg() in the parser definition.
- Verify the field name sent matches a registered ParseField (including all deprecated aliases) so the value actually populates the slot.
Example fix
// before: parser requires 'name' and 'type' as constructor args, input omits 'type'
{"name": "foo"}
// after
{"name": "foo", "type": "bar"} Defensive patterns
Strategy: validation
Validate before calling
// before calling apply(), confirm all required constructor-arg fields are present
Set<String> required = Set.of("name", "type"); // fields declared via constructorArg()
Map<String,Object> body = parseToMap(parserClone);
if (!body.keySet().containsAll(required)) {
throw new IllegalArgumentException("missing required fields: " + Sets.difference(required, body.keySet()));
} Try / catch
try {
Value v = cop.apply(parser, ctx);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Required [")) {
// collect missing fields from message and ask the client to supply them
}
} Prevention
- Document the required constructor-arg fields in the API/endpoint spec so clients send them.
- Validate presence of mandatory fields at the controller layer before delegating to the parser.
- Use optionalConstructorArg() for fields that are genuinely optional to avoid over-constraining.
When it happens
Trigger: Input object omits one or more fields declared with constructorArg() (required). Sending a subset of the required fields, or sending them under deprecated/alternate names not registered, leaves the slot null.
Common situations: Client sends a partial request body missing mandatory fields. Field renamed between versions and the old name no longer maps. Test fixtures that don't include all required fields.
Related errors
- [{name}] failed to parse object
- [{name}] failed to parse field [{field}]
- failed to build [{name}] after last required field arrived
- Failed to build [{name}] after last required field arrived
- Input does not start with Smile format header
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/43f957e20e7ccfd8.
Report an issue: GitHub.