elastic/elasticsearch · error · IllegalArgumentException

Expected a POINT, got [{}]

Error message

Expected a POINT, got [{}]

What it means

parseMultiPoint (line 725) reads the declared point count, then for each element calls parseGeometry (line 732) and checks instanceof Point (line 733). If a sub-element is not a Point, it throws IllegalArgumentException at line 736 with the actual type. This guards WKB structural integrity: a MULTIPOINT (type 4/1004) must contain only Point elements.

Source

Thrown at libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownBinary.java:736

        if (holes.isEmpty()) {
            return new Polygon(shell);
        } else {
            return new Polygon(shell, Collections.unmodifiableList(holes));
        }
    }

    private static MultiPoint parseMultiPoint(ByteBuffer byteBuffer) {
        final int numPoints = byteBuffer.getInt();
        if (numPoints == 0) {
            return MultiPoint.EMPTY;
        }
        final List<Point> points = new ArrayList<>(numPoints);
        for (int i = 0; i < numPoints; i++) {
            final Geometry geometry = parseGeometry(byteBuffer, false);
            if (geometry instanceof Point p) {
                points.add(p);
            } else {
                throw new IllegalArgumentException("Expected a " + ShapeType.POINT + ", got [" + geometry.type() + "]");
            }

        }
        return new MultiPoint(Collections.unmodifiableList(points));
    }

    private static MultiLine parseMultiLine(ByteBuffer byteBuffer) {
        final int numLines = byteBuffer.getInt();
        if (numLines == 0) {
            return MultiLine.EMPTY;
        }
        final List<Line> lines = new ArrayList<>(numLines);
        for (int i = 0; i < numLines; i++) {
            final Geometry geometry = parseGeometry(byteBuffer, false);
            if (geometry instanceof Line l) {
                lines.add(l);
            } else {
                throw new IllegalArgumentException("Expected a " + ShapeType.LINESTRING + ", got [" + geometry.type() + "]");

View on GitHub (pinned to db6a809a66)

Solutions

  1. Validate the producer's WKB output against a known-good reference decoder before exchange.
  2. If you control the producer, ensure MULTIPOINT sub-elements carry type code 1 (or 1001 for Z).
  3. Re-emit the geometry from a trusted source (re-serialize via WellKnownBinary.toWKB) to normalize.
  4. Catch IllegalArgumentException and quarantine the offending record for inspection.

Example fix

// before — corrupt MULTIPOINT WKB
Geometry g = WellKnownBinary.fromWKB(v, false, corruptBytes); // throws: Expected a POINT, got [LINESTRING]

// after — re-serialize from a trusted source
MultiPoint mp = new MultiPoint(List.of(new Point(0,0), new Point(1,1)));
byte[] clean = WellKnownBinary.toWKB(mp, ByteOrder.LITTLE_ENDIAN);
Geometry g = WellKnownBinary.fromWKB(v, false, clean);
Defensive patterns

Strategy: validation

Validate before calling

// Structural integrity of a MULTIPOINT WKB cannot be cheaply pre-validated without parsing.
// Best practice: re-emit from a trusted source.
byte[] normalize(MultiPoint mp) { return WellKnownBinary.toWKB(mp, ByteOrder.LITTLE_ENDIAN); }

Type guard

// no useful type guard on raw bytes; validate via round-trip from a trusted producer

Try / catch

try {
    return WellKnownBinary.fromWKB(v, false, wkb);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Expected a POINT")) {
        // quarantine corrupt MULTIPOINT record for inspection
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling WellKnownBinary.fromWKB with a MULTIPOINT WKB whose sub-elements encode a non-Point geometry (e.g. a producer wrote Line or Polygon bytes inside a MULTIPOINT wrapper). Typical cause is producer bugs, buffer corruption, or endianness misalignment that makes the sub-element's type code parse as a non-Point.

Common situations: Cross-system WKB exchange where the producer serializes MULTIPOINT incorrectly (some libraries allow mixed-type multi-geometries). Truncation/offset errors when slicing buffers. Bit flips in transit/storage. Custom WKB emitters that get the sub-element type code wrong.

Related errors


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