The error IllegalArgumentException: mapper [field] conflicts with existing mapping is thrown when you attempt to map a field with a type or core parameter that contradicts the field's current mapping in the same index, or when a multi-index query (wildcard, alias, data stream) references a field that is mapped differently across the targeted indices. Field types are immutable in Elasticsearch: once field is mapped as text, you cannot remap it as keyword on the same index. The fix is almost always to reindex into a fresh index with the correct mapping.
What This Error Means
Elasticsearch enforces single-typed fields per index because every Lucene index has a fixed schema per field. Changing a field's type would require rewriting every segment that contains the field. Rather than support an expensive online schema change, Elasticsearch refuses to update the mapping in a conflicting way.
The same error appears at search time when a wildcard or alias resolves to multiple indices that disagree on a field's type. A single query cannot run against field as both long and keyword. The full message looks like:
Mapper for [price] conflicts with existing mapping:
[mapper [price] cannot be changed from type [text] to [keyword]]
or:
Cannot use [price] of type [long] and [keyword] on the same query
Common Causes
- Re-applying an index template with a changed field type. New backing indices created after the template change inherit the new type; older indices keep the old type, and a cross-index query trips the conflict.
- Dynamic mapping inferring different types from the first document seen. Index A indexes
price: "19.99"(a string, mapped as text/keyword); index B indexesprice: 19.99(a number, mapped as float). A cross-index query onpricefails. - Renaming a field's type via PUT mapping. Only additive changes are allowed (new fields, new multi-fields, some parameter relaxations). Changing the core type is rejected.
- Reindexing into an existing index with a different mapping. The source mapping leaks into the target unless the target's mapping is set explicitly first.
- Two indices behind the same alias mapping the same logical field differently after a schema evolution.
How to Fix the Mapping Conflict
- Identify the conflicting field and the indices involved. Field Capabilities API surfaces this directly:
The response shows each indexed type and the indices on each side.GET <pattern>/_field_caps?fields=<field> - Decide which type is correct going forward. Usually one type was intended and the other is the accident. If both are real (you have legitimately heterogeneous data), the structural fix is to rename one of them.
- Create a new index with the correct mapping. Declare the field explicitly; do not rely on dynamic mapping.
- Reindex from the conflicting index into the new one. Use the Reindex API with a script that coerces the field to the target type:
POST _reindex { "source": { "index": "old-index" }, "dest": { "index": "new-index" }, "script": { "source": "ctx._source.price = ctx._source.price != null ? ctx._source.price.toString() : null;" } } - Cut traffic over via aliases. Atomically swap the alias from the old index to the new one with
POST _aliases. - Delete the old index once verified.
If the conflict is across multiple live indices (template-evolution case), the same procedure applies to each affected index. An alias with a write-target makes the migration zero-downtime.
Resolve Mapper Conflicts Automatically with Pulse
Pulse is an AI DBA for Elasticsearch and OpenSearch. When IllegalArgumentException: mapper [field] conflicts with existing mapping (or Cannot use [field] of type [X] and [Y] on the same query) blocks indexing or a cross-index search, Pulse:
- Runs
GET <pattern>/_field_caps?fields=<field>across the failing query's targets, lists each indexed type and the indices on each side of the divergence, traces the divergence back to the originating index template, component template, dynamic-mapping inference, or manualPUT /<index>/_mappingcall - Identifies which of the five causes applies: re-applied index template with a changed field type, dynamic mapping inferring different types from the first document, type renamed via
PUT mapping, reindex into an existing index with conflicting mapping, or two indices behind the same alias mapping the same logical field differently - Generates the exact remediation: the new-index mapping with the field declared explicitly, the
POST _reindexpayload with the Painlessctx._source.<field>coercion script, and thePOST _aliasesatomic swap. For unified prevention, thedynamic: strictsetting and shared component template definitions - Applies template and alias updates with operator approval; leaves reindex jobs as one-click PRs with the coercion script ready for review
Pulse continuously checks mapping consistency across query-target patterns and alerts on type divergence as soon as a new index is created with a conflicting mapping - usually surfacing the upstream commit, deployment, or ILM transition that introduced it, which is the bit postmortems normally miss.
Start a free trial to connect your cluster.
Frequently Asked Questions
Q: Can I change a field's type in Elasticsearch without reindexing?
A: No. Field types are immutable on an existing index. The only way to change a field's type is to create a new index with the corrected mapping and reindex documents from the old index, optionally coercing values in a Painless script during the reindex.
Q: How do I add a new field to a mapping without triggering this error?
A: Use PUT /<index>/_mapping with the new field declaration. Adding fields is additive and never produces a conflict, as long as the new field name doesn't already exist with a different type. See add field to mapping.
Q: Why do I get a mapping conflict on a query across multiple indices?
A: The targeted indices mapped the same field with different types. Even if each index is individually consistent, the cross-index query cannot resolve which type to use. Run GET <pattern>/_field_caps?fields=<field> to identify which indices disagree, then reindex one side to unify the type.
Q: How do I prevent mapping conflicts across many indices?
A: Define the field once in a component template; reference the component template from every index template that produces those indices. This keeps the field type identical across every backing index. Combine with dynamic: strict to reject any document that would introduce a typeless field.
Q: Can I have different types for the same field name in different indices?
A: Yes, mechanically. But any query that targets both indices will fail with this error. Either keep query targets segregated by type, or unify the mapping via reindex.
Q: What's the safest way to migrate a field type in production?
A: Create a new index with the corrected mapping, reindex with the necessary coercion script, and use an alias to swap read traffic atomically. Keep the old index for rollback until validation completes, then delete it. Combine with ILM and aliases for zero-downtime cutover.
Q: What's the fastest way to diagnose mapper conflicts in production?
A: Pulse, the AI DBA for Elasticsearch and OpenSearch, runs _field_caps across the failing query pattern, lists each conflicting index and type, traces the divergence back to its originating template or deployment, and proposes the reindex plan with the right Painless coercion. It applies template fixes with operator approval and watches future indices for the same conflict pattern.
Related Reading
- Elasticsearch cross-index query: cross-index queries are where this error surfaces most often.
- Elasticsearch create index with mapping: declare types up front to prevent conflicts.
- Elasticsearch add field to mapping: the safe additive operation that won't trigger this error.
- Elasticsearch index.mapping.total_fields.limit: the other common indexing-time mapping error.
- Elasticsearch nested field data type: nested-to-object changes are a frequent conflict source.
- Elasticsearch dense_vector field data type: dims and similarity are immutable and produce this error on attempted change.