How to fix illegal_argument_exception: Fielddata is disabled on text fields by default. Set fielddata=true on [field] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead. in Elasticsearch

ElasticsearchINTERMEDIATEMEDIUMUpdated Oct 26, 2026ยท 6 views

Elasticsearch rejects aggregations, sorting and scripts on analyzed text fields. Run them on a keyword sub-field such as field.keyword instead of enabling fielddata.

Quick fix

Fixes illegal_argument_exception: Fielddata is disabled on text fields by default. Set fielddata=true on [field] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.

GET my-index/_mapping/field/status
  1. Inspect the field mapping
  2. Aggregate and sort on the keyword sub-field
  3. Add a keyword multi-field to the existing mapping
  4. Populate the new sub-field for existing documents
elasticsearch โ€” error
GET my-index/_mapping/field/status
illegal_argument_exception: Fielddata is disabled on text fields by default. Set fielddata=true on [field] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.

What this error means

Elasticsearch stores `text` fields in an inverted index built for full-text search. Aggregations, sorting and scripts need the opposite structure: per-document values. `keyword` fields get those from on-disk doc values, but `text` fields have no doc values. The only way to get per-document data for a `text` field is fielddata, which un-inverts the inverted index and keeps the result on the JVM heap. Because that is expensive, fielddata is disabled on `text` fields by default, and any request that needs it fails with an `illegal_argument_exception`. Older releases (5.x and 6.x) word it as "Fielddata is disabled on text fields by default. Set fielddata=true on [field] ...". In newer 7.x releases and in 8.x the message reads "Fielddata is disabled on [field] in [index]. Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [field] ...". Both mean the same thing. The fix is almost never to turn fielddata on. Point the aggregation or sort at a `keyword` field, usually the `.keyword` sub-field that dynamic mapping creates for strings.

Typical symptoms

  • A terms aggregation or a Kibana visualization on a string field fails with illegal_argument_exception
  • A search with "sort" on a string field returns HTTP 400 and the fielddata message
  • A painless script that reads doc['field'].value on a text field fails
  • The search response reports failed shards whose reason names the text field
  • An application built on Elasticsearch (Magento, Liferay, Graylog) shows a search error after a mapping change

Common causes

  1. The query aggregates or sorts on the text field (for example "status") instead of its keyword sub-field ("status.keyword").
  2. An explicit mapping or index template defines the field as text only, with no keyword sub-field.
  3. A script reads the text field through doc values (doc['field']).
  4. A field that used to be keyword was remapped as text in a new index or template, so existing queries now hit a text field.

How to fix "illegal_argument_exception: Fielddata is disabled on text fields by default. Set fielddata=true on [field] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."

1Inspect the field mapping

Check how the field is actually mapped before changing anything. This is read-only:

bash
GET my-index/_mapping/field/status

or for the whole index:

bash
GET my-index/_mapping

If the field is "type": "text" and has a fields.keyword entry, go to the next step. If it is text with no keyword sub-field, skip to step 3.

2Aggregate and sort on the keyword sub-field

Dynamic mapping maps a JSON string to text with a .keyword sub-field, so in most cases you only need to change the field name in the query:

json
GET my-index/_search
{
  "size": 0,
  "aggs": {
    "by_status": {
      "terms": { "field": "status.keyword" }
    }
  },
  "sort": [ { "status.keyword": "asc" } ]
}

Keep using status (the text field) in match queries for full-text search. In Kibana, pick the .keyword field in the visualization or data view.

3Add a keyword multi-field to the existing mapping

If the field has no keyword sub-field, add one with the update mapping API. Adding a multi-field to an existing field is allowed:

json
PUT my-index/_mapping
{
  "properties": {
    "status": {
      "type": "text",
      "fields": {
        "keyword": { "type": "keyword", "ignore_above": 256 }
      }
    }
  }
}

Repeat the field's existing parameters (such as analyzer) exactly, or the update is rejected as a conflict. Update the index template too, so new indices get the sub-field.

4Populate the new sub-field for existing documents

Documents indexed before the mapping change have no values in the new multi-field, so aggregations on it only see new documents. Re-index them in place with update by query, which picks up the new mapping:

bash
POST my-index/_update_by_query?conflicts=proceed&wait_for_completion=false

Track the returned task with GET _tasks/<task_id>. On a large index this is heavy, so run it off-peak.

5Reindex if the field must change type

You cannot change an existing field's type (for example text to keyword) in place. Create a new index with the correct mapping and copy the data:

json
PUT my-index-v2
{
  "mappings": {
    "properties": {
      "status": { "type": "keyword" }
    }
  }
}

POST _reindex
{
  "source": { "index": "my-index" },
  "dest": { "index": "my-index-v2" }
}

Then point an alias at the new index so applications do not need the new name.

6Enable fielddata only as a last resort

If you really need aggregations on the analyzed tokens of a text field (for example a word cloud), you can enable fielddata:

json
PUT my-index/_mapping
{
  "properties": {
    "body": {
      "type": "text",
      "fielddata": true
    }
  }
}

Fielddata is loaded onto the JVM heap and aggregates individual tokens, not whole values: "New York" becomes the buckets new and york. On high-cardinality fields it can trip the fielddata circuit breaker (indices.breaker.fielddata.limit, 40% of heap by default) or cause latency spikes and heap pressure. Do not use it to get whole-value aggregations; use a keyword field for that.

Advanced notes

If you must enable fielddata, fielddata_frequency_filter (with min, max and min_segment_size) limits which terms are loaded into memory and reduces heap use. Fielddata is built lazily on the first query that needs it, so that first query can be slow.

The keyword sub-field created by dynamic mapping uses ignore_above: 256. Strings longer than that are still searchable through the text field but are not indexed in .keyword, so they do not appear in aggregations or sort on it.

When many indices share the problem (for example time-based log indices), fix the index template first. Existing indices keep their old mapping until they roll over or are reindexed.

Frequently asked questions

What does "illegal_argument_exception: Fielddata is disabled on text fields by de" mean?
Elasticsearch stores text fields in an inverted index built for full-text search. Aggregations, sorting and scripts need the opposite structure: per-document values. keyword fields get those from on-disk doc values, but text fields have no doc values.
How do I fix "illegal_argument_exception: Fielddata is disabled on text fields by de"?
Elasticsearch rejects aggregations, sorting and scripts on analyzed text fields. Run them on a keyword sub-field such as field.keyword instead of enabling fielddata.
What causes "illegal_argument_exception: Fielddata is disabled on text fields by de"?
The query aggregates or sorts on the text field (for example "status") instead of its keyword sub-field ("status.keyword"). An explicit mapping or index template defines the field as text only, with no keyword sub-field. A script reads the text field through doc values (doc['field']).
Is the "illegal_argument_exception: Fielddata is disabled on text fields by de" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading