elastic/elasticsearch · error · IllegalArgumentException

cannot expand [ ], because [ ] is not an object field, but…

Error message

cannot expand [{}], because [{}] is not an object field, but a value field

What it means

Thrown by DotExpanderProcessor.execute when expanding a dotted field name into nested objects would require converting an existing leaf value into a map. The processor walks each dotted prefix and verifies that any existing value at that prefix is a Map; if it finds a scalar (string, number, etc.) it aborts, because overwriting a leaf with an object would silently destroy data. The error names both the full path and the conflicting partial path.

Solutions

  1. Rename or remove the conflicting scalar field (or its parent) before the dot_expander processor runs.
  2. Restructure the producer so the field is consistently an object.
  3. Use a 'convert' or 'script' processor to coerce the scalar into a map shape before expansion, or use 'override' carefully.
  4. Quarantine the document via on_failure if it is genuinely ambiguous.

Example fix

// before - document has a="hello" and dot_expander expands a.b="x"
{"dot_expander": {"field": "a.b"}}
// after - rename the conflicting scalar first
{"rename": {"field": "a", "target_field": "a_value", "ignore_missing": true}},
{"dot_expander": {"field": "a.b"}}
Defensive patterns

Strategy: type-guard

Validate before calling

// Guard before dot_expander: skip if any prefix would collide with a scalar.
{"script": {"source": "def p = 'a'; if (ctx.containsKey(p) && !(ctx[p] instanceof Map)) { ctx.a_value = ctx.a; ctx.remove('a'); }"}}

Type guard

// painless
boolean prefix_is_map_or_absent(def doc, String prefix) { return doc[prefix] == null || doc[prefix] instanceof Map; }

Try / catch

{"on_failure": [{"index": {"index": "ingest-dlq"}}]}

Prevention

When it happens

Trigger: A document where 'a' already exists as a string and the dot_expander is asked to expand 'a.b'. The partial path 'a' is a value field, not a map, so expansion of 'a.b' is rejected.

Common situations: Heterogeneous documents where the same key is sometimes a scalar and sometimes a parent object; field collisions after rename or enrichment processors; producing systems that flatten some keys but not others; JSON with inconsistent nesting.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/427ef0dd2bd1f112. Report an issue: GitHub.

Appendix: source

Thrown at modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/DotExpanderProcessor.java:86

        if (map.containsKey(fieldName)) {
            if (ingestDocument.hasField(pathToExpand)) {
                Object value = map.remove(fieldName);
                if (override) {
                    ingestDocument.setFieldValue(pathToExpand, value);
                } else {
                    ingestDocument.appendFieldValue(pathToExpand, value);
                }
            } else {
                // check whether we actually can expand the field in question into an object field.
                // part of the path may already exist and if part of it would be a value field (string, integer etc.)
                // then we can't override it with an object field and we should fail with a good reason.
                // IngestDocument#setFieldValue(...) would fail too, but the error isn't very understandable
                for (int index = pathToExpand.indexOf('.'); index != -1; index = pathToExpand.indexOf('.', index + 1)) {
                    String partialPath = pathToExpand.substring(0, index);
                    if (ingestDocument.hasField(partialPath)) {
                        Object val = ingestDocument.getFieldValue(partialPath, Object.class);
                        if ((val instanceof Map) == false) {
                            throw new IllegalArgumentException(
                                "cannot expand ["
                                    + pathToExpand
                                    + "], because ["
                                    + partialPath
                                    + "] is not an object field, but a value field"
                            );
                        }
                    } else {
                        break;
                    }
                }
                Object value = map.remove(fieldName);
                ingestDocument.setFieldValue(pathToExpand, value);
            }
        }
    }

    @Override

View on GitHub (pinned to db6a809a66)