Logstash Error Guide: 'Limit of total fields [1000] has been exceeded' — Stop the Mapping Explosion
Fix Logstash 'Limit of total fields [1000] has been exceeded': find the high-cardinality keys, control dynamic mapping, and prune fields before they explode.
- #logstash
- #logging
- #troubleshooting
- #errors
Stuck on this Logstash error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
What this error means
Elasticsearch caps the number of fields an index mapping may contain (default 1000). When Logstash keeps sending events with new, previously-unseen field names, dynamic mapping adds each one — until the index hits the ceiling and the elasticsearch output starts rejecting documents:
[WARN ][logstash.outputs.elasticsearch] Could not index event to Elasticsearch.
{:status=>400, :action=>["index", {:_index=>"app-logs-2026.07.11"}, {...}],
:response=>{"index"=>{"error"=>{
"type"=>"illegal_argument_exception",
"reason"=>"Limit of total fields [1000] in index [app-logs-2026.07.11] has been exceeded"}}}}
This is a mapping explosion: it’s rarely a legitimate schema of 1000 fields and almost always a handful of high-cardinality keys being promoted to fields — per-request IDs used as JSON keys, dynamic labels, or an unparsed blob exploded by a json/kv filter. Every event after the limit is a non-retryable 400 and is dropped (or sent to the DLQ).
Warning signs
Limit of total fields [N] in index [...] has been exceededwithillegal_argument_exceptionand:status=>400.- New documents stop appearing in Kibana while old ones remain; the failure is index-wide, not per-source.
- The index’s mapping is huge and full of one-off field names (UUIDs, timestamps, or IDs as keys).
- Errors began after adding a
json/kvfilter, ingesting a new app, or a code change that emits dynamic keys. - Cluster state grows and master nodes get slower as the mapping bloats.
Measuring the limit
Confirm the error and which index is affected:
grep 'Limit of total fields' /var/log/logstash/logstash-plain.log | tail -5
Count the fields actually in the mapping — a number near the limit confirms explosion:
curl -s 'http://es:9200/app-logs-2026.07.11/_mapping?pretty' | grep -c '"type"'
Look at the field names to spot the pattern — long lists of UUID/ID-like keys are the tell:
curl -s 'http://es:9200/app-logs-2026.07.11/_mapping?pretty' \
| grep -oE '"[a-f0-9-]{16,}"' | head
Check whether the current limit was already raised:
curl -s 'http://es:9200/app-logs-2026.07.11/_settings?pretty' | grep total_fields
Limits and pressure causes
- High-cardinality keys promoted to fields — JSON objects keyed by user/request/trace ID (
{"req_9f3a...": {...}}), so every request mints a new field. kvfilter on free-form text — key=value parsing of arbitrary logs invents a field per distinct key.jsonfilter on a deeply dynamic payload — expanding a nested object whose keys are data, not schema.- Metrics/labels as fields — Prometheus-style label sets or per-tenant attributes flattened into distinct mappings.
- No dynamic-mapping policy — the index lets Elasticsearch map every new field it sees, with no
dynamic: falseguardrail. - Limit raised instead of fixed — someone bumped
total_fields.limitto 5000, delaying the same crash.
Remediation
1. Stop promoting high-cardinality keys — keep the dynamic blob as data, not schema. Nest it under one field and disable mapping of its contents in a composable template:
PUT _index_template/app-logs
{
"index_patterns": ["app-logs-*"],
"template": {
"settings": { "index.mapping.total_fields.limit": 1000 },
"mappings": {
"dynamic": true,
"properties": {
"raw_payload": { "type": "object", "enabled": false }
}
}
}
}
enabled: false stores the object but indexes none of its keys, so it can’t add fields.
2. Move the dynamic data into one non-exploding field in the Logstash filter, instead of letting json/kv spray keys:
filter {
# Instead of json { source => "msg" } which explodes dynamic keys,
# keep the blob intact under a disabled field:
mutate { rename => { "msg" => "raw_payload" } }
}
3. Constrain the kv filter so it only extracts known keys rather than every token:
filter {
kv {
source => "message"
include_keys => ["user", "status", "path", "duration"] # allow-list only
remove_char_key => " "
}
}
4. Prune the noise before output — drop dynamic fields you don’t query:
filter {
prune {
whitelist_names => ["^@timestamp$", "^message$", "^host", "^user$",
"^status$", "^path$", "^duration$", "^raw_payload$"]
}
}
5. Add a dynamic-mapping guardrail so unknown strings map to keyword (cheap) and objects don’t recurse into new fields:
"dynamic_templates": [
{ "strings_as_keywords": {
"match_mapping_type": "string",
"mapping": { "type": "keyword", "ignore_above": 256 } } }
]
Then roll over to a new index so the template takes effect (mappings are immutable in place).
Capacity headroom
- Raising
index.mapping.total_fields.limitis a stopgap, not a fix — it postpones the same crash and bloats cluster state; fix the cardinality instead. - The limit is per index, so a rollover to a fresh index temporarily clears the error but the explosion resumes unless the root cause is fixed.
enabled: falsemakes a field’s contents unsearchable/unaggregatable — good for opaque blobs, wrong for data you actually query, so choose per field.kvandjsonon free-form text are the usual culprits; always allow-list keys or keep the payload intact under one disabled object.- Fixing the template only affects newly created indices; the bloated current index needs a rollover, and historical data a reindex, to shrink.
- Enable the DLQ so events rejected during the explosion are captured rather than silently dropped while you remediate.
Related capacity errors
- Logstash Error Guide: mapper_parsing_exception
- Logstash Error Guide: retrying failed action … 429
- Logstash Error Guide: dead letter queue is full
Fixed it? Get 500 Logstash & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Trending errors this week
The error guides other engineers are actually reading right now.
- 1mount: wrong fs type, bad option, bad superblock
- 2Docker 'failed to set up container networking': Fix the Bridge and IP Pool
- 3Docker 'failed to create shim task': How to Fix the containerd Runtime Error
- 4modprobe: FATAL: Module not found
- 5mount: wrong fs type, bad option, bad superblock
- 6Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.