elastic/elasticsearch · error · XContentParseException

Failed to build [{name}] after last required field arrived

Error message

Failed to build [{name}] after last required field arrived

What it means

The sibling branch of buildTarget: if the builder BiFunction (or a flushed queued consumer) throws any Exception that is NOT an XContentParseException, it is wrapped with a null location and a capitalized message. This catches generic construction failures such as IllegalArgument/IllegalState/ClassCast from the builder's own validation or from reflective instantiation.

Source

Thrown at libs/x-content/src/main/java/org/elasticsearch/xcontent/ConstructingObjectParser.java:591

        private void buildTarget() {
            try {
                targetObject = builder.apply(constructorArgs, context);
                if (queuedOrderedModeCallback != null) {
                    queuedOrderedModeCallback.accept(targetObject);
                }
                while (queuedFieldsCount > 0) {
                    queuedFieldsCount -= 1;
                    queuedFields[queuedFieldsCount].accept(targetObject);
                }
            } catch (XContentParseException e) {
                throw new XContentParseException(
                    e.getLocation(),
                    "failed to build [" + objectParser.getName() + "] after last required field arrived",
                    e
                );
            } catch (Exception e) {
                throw new XContentParseException(
                    null,
                    "Failed to build [" + objectParser.getName() + "] after last required field arrived",
                    e
                );
            }
        }
    }

    private static class ConstructorArgInfo {
        final ParseField field;
        final boolean required;

        ConstructorArgInfo(ParseField field, boolean required) {
            this.field = field;
            this.required = required;
        }
    }
}

View on GitHub (pinned to db6a809a66)

Solutions

  1. Read the cause: for IllegalArgumentException it usually states the failed invariant (range, enum, arity) — fix the input or the builder accordingly.
  2. If the cause is a ClassCastException, the declared ValueType for a field does not match what the builder expects; align them.
  3. Prefer failing inside a field consumer with an XContentParseException (which carries location) over throwing raw IllegalArgumentException in the builder.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    Value v = cop.apply(parser, ctx);
} catch (XContentParseException e) {
    if (e.getMessage().startsWith("Failed to build [") && e.getLocation() == null) {
        Throwable root = e.getCause(); // IllegalArgumentException/ClassCastException etc.
    }
}

Prevention

When it happens

Trigger: Builder lambda performs casts or range checks that throw IllegalArgumentException, passes wrong-typed args to a constructor, or a queued field consumer mutates state that violates an invariant. Reflective instantiation failures surfaced here when used via InstantiatingObjectParser.

Common situations: Builder that asserts numeric ranges or enum membership and throws on invalid input. Type-cast bugs in the builder where the declared ValueType doesn't match the runtime type. Constructor argument count/type mismatch.

Related errors


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