elastic/elasticsearch · error · ParseException
Unknown geometry type:
Error message
Unknown geometry type:
What it means
WellKnownBinary.fromWKT (the WKT-to-WKB direct converter) reads a leading type word at line 257 and dispatches via a switch (lines 260-269) over the recognized WKT type names: point, multipoint, linestring, multilinestring, polygon, multipolygon, geometrycollection, circle, bbox. Any other word hits the default branch at line 270 and throws ParseException with the offending type and the line number. This is a parse-time, input-driven error, not a logic error.
Source
Thrown at libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownBinary.java:270
ByteBuffer scratch,
boolean coerce,
int depth,
GeometryValidator validator
) throws IOException, ParseException {
final String type = WellKnownText.nextWord(stream).toLowerCase(Locale.ROOT);
final boolean explicitZ = WellKnownText.isZOrMNext(stream);
out.write(scratch.order() == ByteOrder.BIG_ENDIAN ? 0 : 1);
switch (type) {
case "point" -> writeWKBPoint(stream, out, scratch, explicitZ, validator);
case "multipoint" -> writeWKBMultiPoint(stream, out, scratch, explicitZ, validator);
case "linestring" -> writeWKBLineString(stream, out, scratch, explicitZ, validator);
case "multilinestring" -> writeWKBMultiLineString(stream, out, scratch, explicitZ, validator);
case "polygon" -> writeWKBPolygon(stream, out, scratch, coerce, explicitZ, validator);
case "multipolygon" -> writeWKBMultiPolygon(stream, out, scratch, coerce, explicitZ, validator);
case "geometrycollection" -> writeWKBGeometryCollection(stream, out, scratch, coerce, depth, explicitZ, validator);
case "circle" -> writeWKBCircle(stream, out, scratch, explicitZ, validator);
case "bbox" -> writeWKBBBox(stream, out, scratch, explicitZ, validator);
default -> throw new ParseException("Unknown geometry type: " + type, stream.lineno());
}
}
private static void writeWKBPoint(
StreamTokenizer stream,
ByteArrayOutputStream out,
ByteBuffer scratch,
boolean explicitZ,
GeometryValidator validator
) throws IOException, ParseException {
if (WellKnownText.nextEmptyOrOpen(stream).equals(WellKnownText.EMPTY)) {
throw new IllegalArgumentException("Empty POINT cannot be represented in WKB");
}
double x = WellKnownText.nextNumber(stream);
double y = WellKnownText.nextNumber(stream);
double z = Double.NaN;
if (WellKnownText.isNumberNext(stream)) {
z = WellKnownText.nextNumber(stream);View on GitHub (pinned to db6a809a66)
Solutions
- Validate the leading token against the supported set {POINT, MULTIPOINT, LINESTRING, MULTILINESTRING, POLYGON, MULTIPOLYGON, GEOMETRYCOLLECTION, CIRCLE, BBOX} before calling fromWKT.
- Pre-process input: strip EWKT SRID prefixes (e.g. 'SRID=4326;') and reject unsupported extended types upstream.
- For unsupported geometry types, convert to a supported equivalent (e.g. triangulate TINs, sample curves) before serialization.
- Catch ParseException and report a user-facing error with the offending type and line number from the exception.
Example fix
// before
byte[] wkb = WellKnownBinary.fromWKT("TRIANGLE((0 0, 1 0, 0 1, 0 0))", ByteOrder.LITTLE_ENDIAN, false);
// throws: Unknown geometry type: triangle
// after — convert to a supported type (Polygon) first
String wkt = "POLYGON((0 0, 1 0, 0 1, 0 0))";
byte[] wkb = WellKnownBinary.fromWKT(wkt, ByteOrder.LITTLE_ENDIAN, false); Defensive patterns
Strategy: validation
Validate before calling
static final Set<String> WKB_WKT_TYPES = Set.of(
"point","multipoint","linestring","multilinestring",
"polygon","multipolygon","geometrycollection","circle","bbox");
boolean isSupportedWktType(String wkt) {
String head = wkt.trim().split("[\\s(]", 2)[0].toLowerCase(Locale.ROOT);
return WKB_WKT_TYPES.contains(head);
} Type guard
static String headType(String wkt) {
String t = wkt.trim().split("[\\s(]", 2)[0];
return t == null ? "" : t.toLowerCase(Locale.ROOT);
} Try / catch
try {
return WellKnownBinary.fromWKT(wkt, bo, coerce, v);
} catch (ParseException e) {
if (e.getMessage().startsWith("Unknown geometry type")) {
throw new IllegalArgumentException("Unsupported WKT type in input", e);
}
throw e;
} Prevention
- Validate the leading WKT type token against the supported set before fromWKT.
- Strip EWKT SRID prefixes and reject SQL-MM extended types at the API boundary.
- Surface ParseException line numbers to the user for fast diagnosis.
When it happens
Trigger: Calling WellKnownBinary.fromWKT(wkt, ...) with a WKT string whose leading token is not one of the nine recognized type keywords (e.g. 'TRIANGLE(...)', 'TIN(...)', 'GEOMETRY(...)', typos like 'POING(...)', or leading whitespace/punctuation that the tokenizer mis-segments). Case is normalized via toLowerCase(Locale.ROOT) at line 257 so case is not the cause.
Common situations: Ingesting WKT produced by tools that emit extended OGC/SFA types (CurvePolygon, PolyhedralSurface, Triangle, Tin) not supported by this library. Pasting WKT from documentation that uses a different dialect. User input with typos or non-Latin lookalike characters. Feeding non-WKT strings (GeoJSON, EWKT with SRID prefix) into fromWKT.
Related errors
- Empty POINT cannot be represented in WKB
- holes must have the same number of dimensions as the polygon
- all elements of the collection should have the same number o
- maximum nested depth of
- Empty CIRCLE cannot be represented in WKB
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/afc90d1fb7f41be8.
Report an issue: GitHub.