elastic/elasticsearch · error · XContentParseException
[{}] Expected START_OBJECT but was: {}
Error message
[{}] Expected START_OBJECT but was: {} What it means
Thrown when ObjectParser.parse() is called and the first token from XContentParser is not START_OBJECT. ObjectParser expects to read a JSON/YAML object (opening brace '{') as its top-level structure; any other leading token (START_ARRAY, VALUE_STRING, VALUE_NUMBER, END_OBJECT, etc.) triggers this error via throwExpectedStartObject.
Source
Thrown at libs/x-content/src/main/java/org/elasticsearch/xcontent/ObjectParser.java:331
maybeMarkExclusiveField(currentFieldName, exclusiveFields);
}
parseSub(parser, fieldParser, token, currentFieldName, value, context);
}
}
// Check for a) multiple entries appearing in exclusive field sets and b) empty required field entries
if (exclusiveFields != null) {
ensureExclusiveFields(exclusiveFields);
}
if (requiredFields != null && requiredFields.isEmpty() == false) {
throwMissingRequiredFields(requiredFields);
}
return value;
}
private void throwExpectedStartObject(XContentParser parser, XContentParser.Token token) {
throw new XContentParseException(parser.getTokenLocation(), "[" + name + "] Expected START_OBJECT but was: " + token);
}
private static void throwMissingRequiredFields(List<String[]> requiredFields) {
final StringBuilder message = new StringBuilder();
for (int i = 0; i < requiredFields.size(); i++) {
if (i > 0) {
message.append(" ");
}
message.append("Required one of fields ").append(Arrays.toString(requiredFields.get(i))).append(", but none were specified.");
}
throw new IllegalArgumentException(message.toString());
}
private static void ensureExclusiveFields(List<List<String>> exclusiveFields) {
StringBuilder message = null;
for (List<String> fieldset : exclusiveFields) {
if (fieldset.size() > 1) {
if (message == null) {View on GitHub (pinned to db6a809a66)
Solutions
- Ensure the request body is a JSON object starting with '{' and not an array or scalar.
- If the endpoint accepts an array, use the appropriate array-aware parser or endpoint variant.
- Validate the body with a JSON linter before sending.
- Check for double-wrapping (e.g., body already has outer braces but the client adds another layer).
Example fix
// before — array passed where object expected
POST /_search
[{"query": {"match_all": {}}}]
// after — single object
POST /_search
{"query": {"match_all": {}}} Defensive patterns
Strategy: validation
Validate before calling
// Before parsing, verify the first non-whitespace character is '{'
public static void ensureStartObject(String json) {
String trimmed = json.strip();
if (!trimmed.startsWith("{")) {
throw new IllegalArgumentException("Expected a JSON object starting with '{'");
}
} Try / catch
try {
return objectParser.apply(parser, context);
} catch (XContentParseException e) {
if (e.getMessage().contains("Expected START_OBJECT")) {
return ResponseEntity.badRequest().body(e.getMessage());
}
throw e;
} Prevention
- Validate that request bodies are JSON objects, not arrays, before sending to object-expecting endpoints.
- Use JSON schema validation on the request body to enforce object root type.
- Test API calls with a JSON linter or validator before deploying to production.
When it happens
Trigger: Passing a JSON array where the parser expects an object, e.g., sending [{"field":"value"}] to a REST endpoint whose body schema is a single object. Passing a bare scalar (string, number, boolean) where an object body is required. Sending malformed JSON that causes the tokenizer to emit an unexpected first token.
Common situations: Wrapping a request body in square brackets instead of curly braces. Sending a plain string or number to an endpoint that expects an object. A proxy or load balancer rewriting the body. YAML content where indentation produces an unexpected first token.
Related errors
- Required one of fields {}, but none were specified.
- The following fields are not allowed together: {}
- [{}] failed to parse object
- [{}] doesn't support arrays. Use a single object with multip
- [{}] failed to parse field [{}]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/d4f7798ca47891b8.
Report an issue: GitHub.