elastic/elasticsearch · error · IllegalArgumentException
Expected a LINESTRING, got [{}]
Error message
Expected a LINESTRING, got [{}] What it means
parseMultiLine (line 743) reads the declared line count, then for each element calls parseGeometry (line 750) and checks instanceof Line (line 751). A non-Line sub-element triggers IllegalArgumentException at line 754. WKB MULTILINESTRING (type 5/1005) must contain only LineString elements.
Source
Thrown at libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownBinary.java:754
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() + "]");
}
}
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() + "]");
}View on GitHub (pinned to db6a809a66)
Solutions
- Validate producer output against a reference decoder before exchange.
- Ensure MULTILINESTRING sub-elements carry type code 2 (or 1002 for Z) if you control the producer.
- Re-serialize from a trusted geometry object via WellKnownBinary.toWKB to normalize.
- Catch and quarantine corrupt records for offline inspection.
Example fix
// before
Geometry g = WellKnownBinary.fromWKB(v, false, corruptBytes); // throws: Expected a LINESTRING, got [POINT]
// after — re-emit from trusted source
MultiLine ml = new MultiLine(List.of(new Line(new double[]{0,1}, new double[]{0,1})));
byte[] clean = WellKnownBinary.toWKB(ml, 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(MultiLine ml) { return WellKnownBinary.toWKB(ml, 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 LINESTRING")) {
// quarantine corrupt MULTILINESTRING record
}
throw e;
} Prevention
- Re-serialize MULTILINESTRING from a trusted geometry object before exchange.
- Validate producer output against a reference decoder.
- Ensure MULTILINESTRING sub-elements carry type code 2 (or 1002 for Z).
When it happens
Trigger: Calling WellKnownBinary.fromWKB with a MULTILINESTRING WKB whose sub-elements are not LineString-encoded (e.g. Point or Polygon bytes inside the wrapper). Producer bugs, buffer corruption, or endianness misalignment are the usual causes.
Common situations: Interoperability with WKB emitters that allow mixed-type multi-geometries. Truncated/misaligned buffers where a coordinate is misread as a type code. Custom serializers that emit the wrong sub-element type code.
Related errors
- Expected a POINT, got [{}]
- Expected a POLYGON, got [{}]
- Unknown geometry type: {}
- all elements of the collection should have the same number o
- Empty
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/1a4afe41bf9f77d4.
Report an issue: GitHub.