elastic/elasticsearch · error · IllegalArgumentException

Expected a POLYGON, got [{}]

Error message

Expected a POLYGON, got [{}]

What it means

parseMultiPolygon (line 760) reads the declared polygon count, then for each element calls parseGeometry (line 767) and checks instanceof Polygon (line 768). A non-Polygon sub-element triggers IllegalArgumentException at line 771. WKB MULTIPOLYGON (type 6/1006) must contain only Polygon elements.

Source

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

            } else {
                throw new IllegalArgumentException("Expected a " + ShapeType.LINESTRING + ", got [" + geometry.type() + "]");
            }
        }
        return new MultiLine(Collections.unmodifiableList(lines));
    }

    private static MultiPolygon parseMultiPolygon(ByteBuffer byteBuffer, boolean coerce) {
        final int numPolygons = byteBuffer.getInt();
        if (numPolygons == 0) {
            return MultiPolygon.EMPTY;
        }
        final List<Polygon> polygons = new ArrayList<>(numPolygons);
        for (int i = 0; i < numPolygons; i++) {
            final Geometry geometry = parseGeometry(byteBuffer, coerce);
            if (geometry instanceof Polygon p) {
                polygons.add(p);
            } else {
                throw new IllegalArgumentException("Expected a " + ShapeType.POLYGON + ", got [" + geometry.type() + "]");
            }

        }
        return new MultiPolygon(Collections.unmodifiableList(polygons));
    }

    private static GeometryCollection<Geometry> parseGeometryCollection(ByteBuffer byteBuffer, boolean coerce) {
        final int numShapes = byteBuffer.getInt();
        if (numShapes == 0) {
            return GeometryCollection.EMPTY;
        }
        final List<Geometry> shapes = new ArrayList<>(numShapes);
        for (int i = 0; i < numShapes; i++) {
            shapes.add(parseGeometry(byteBuffer, coerce));
        }
        return new GeometryCollection<>(shapes);
    }

View on GitHub (pinned to db6a809a66)

Solutions

  1. Validate producer output against a reference WKB decoder.
  2. Ensure MULTIPOLYGON sub-elements carry type code 3 (or 1003 for Z) if you control the producer.
  3. Re-serialize from a trusted MultiPolygon via WellKnownBinary.toWKB to normalize.
  4. Catch IllegalArgumentException and route the offending record to a dead-letter queue for inspection.

Example fix

// before
Geometry g = WellKnownBinary.fromWKB(v, false, corruptBytes); // throws: Expected a POLYGON, got [MULTIPOINT]

// after — re-emit from trusted source
Polygon p = new Polygon(new LinearRing(new double[]{0,1,1,0}, new double[]{0,0,1,0}));
MultiPolygon mp = new MultiPolygon(List.of(p));
byte[] clean = WellKnownBinary.toWKB(mp, ByteOrder.LITTLE_ENDIAN);
Geometry g = WellKnownBinary.fromWKB(v, false, clean);
Defensive patterns

Strategy: validation

Validate before calling

// No cheap structural pre-check; normalize by re-emitting from trusted source.
byte[] normalize(MultiPolygon mp) { return WellKnownBinary.toWKB(mp, ByteOrder.LITTLE_ENDIAN); }

Type guard

// no useful type guard on raw bytes; validate via round-trip

Try / catch

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

Prevention

When it happens

Trigger: Calling WellKnownBinary.fromWKB with a MULTIPOLYGON WKB whose sub-elements are not Polygon-encoded. Causes: producer bugs allowing mixed-type multi-geometries, buffer corruption, endianness misalignment, or truncation that shifts the sub-element type-code read.

Common situations: Cross-system WKB exchange with emitters that mis-serialize MULTIPOLYGON. Misaligned offsets when slicing a larger buffer. Bit flips in transit/storage. Custom WKB emitters with incorrect sub-element type codes.

Related errors


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