Briefly, this error occurs when an Elasticsearch request is made without a required body or source parameter. This usually happens when you’re trying to perform operations like indexing, updating, or searching documents. To resolve this, ensure that your request includes a valid body or source parameter. Check your request syntax and structure to ensure it’s correct. If you’re using a programming language to send requests, ensure that the request body is properly formatted and not empty.
Before you dig into reading this guide, have you tried asking OpsGPT what this log means? You’ll receive a customized analysis of your log.
Try OpsGPT now for step-by-step guidance and tailored insights into your Elasticsearch/OpenSearch operation.
To fully understand why this error appeared and how to remedy the errors in your query, you should run the AutoOps for Elasticsearch.
This guide will help you understand issues realted to the log “request body or source parameter is required”. To get started, read the general overview on common issues and tips related to the Elasticsearch concepts: rest, request and source.
Background
The Analyze API is used to perform analysis on a text string and return the resulting tokens. The above exception arises when the cURL request of Analyze API is malformed. The proper format, as detailed below in the “How to fix” section, is required to get the tokens using this API.
How to reproduce this exception
In the cURL format, if the Analyze request is written like this:
Hit the Analyze API:
curl -XGET "localhost:9200/my-index/_analyze?analyzer=standard&pretty" -H -d "Opster"
Then the response generated will be:
{ "error": { "root_cause": [ { "type": "parse_exception", "reason": "request body or source parameter is required" } ], "type": "parse_exception", "reason": "request body or source parameter is required" }, "status": 400 }
How to fix this exception
The cURL request is malformed. The query can be modified in the following way:
In cURL format:
curl -XGET "http://localhost:9800/my-index/_analyze?pretty" -H 'Content-Type: application/json' -d '{ "analyzer": "standard", "text": "Opster" }'
The equivalent request in the Kibana Dev Tools format is:
GET /my-index/_analyze?pretty { "analyzer" : "standard", "text" : "opster" }
The tokens generated from the above request are:
{ "tokens": [ { "token": "opster", "start_offset": 0, "end_offset": 4, "type": "<ALPHANUM>", "position": 0 } ] }
To learn more about tokens, you can refer to text analysis for more information.
Overview
When a document is sent for indexing, Elasticsearch indexes all the fields in the format of an inverted index, but it also keeps the original JSON document in a special field called _source.
Examples
Disabling source field in the index:
PUT /api-logs?pretty { "mappings": { "_source": { "enabled": false } } }
Store only selected fields as a part of _source field:
PUT api-logs { "mappings": { "_source": { "includes": [ "*.count", "error_info.*" ], "excludes": [ "error_info.traceback_message" ] } } }
Including only selected fields using source filtering:
GET api-logs/_search { "query": { "match_all": {} }, "_source": { "includes": ["api_name","status_code", "*id"] } }
Notes
The source field brings an overhead of extra storage space but serves special purposes such as:
- Return as a part of the response when a search query is executed.
- Used for reindexing purpose, update and update_by_query operations.
- Used for highlighting, if the field is not stored, it means the field is not set as “store to true” inside the mapping.
- Allows selection of fields to be returned.
The only concern with source field is the extra storage usage on disk. But this storage space used by source field can be optimized by changing compression level to best_compression. This setting is done using index.codec parameter.
Log Context
Log “request body or source parameter is required” class name is RestRequest.java. We extracted the following from Elasticsearch source code for those seeking an in-depth context :
* Get the content of the request or the contents of the {@code source} param or throw an exception if both are missing. * Prefer {@link #contentOrSourceParamParser()} or {@link #withContentOrSourceParamParserOrNull(CheckedConsumer)} if you need a parser. */ public final TuplecontentOrSourceParam() { if (hasContentOrSourceParam() == false) { throw new ElasticsearchParseException("request body or source parameter is required"); } else if (hasContent()) { return new Tuple<>(xContentType.get(); requiredContent()); } String source = param("source"); String typeParam = param("source_content_type");