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

  1. Validate the leading token against the supported set {POINT, MULTIPOINT, LINESTRING, MULTILINESTRING, POLYGON, MULTIPOLYGON, GEOMETRYCOLLECTION, CIRCLE, BBOX} before calling fromWKT.
  2. Pre-process input: strip EWKT SRID prefixes (e.g. 'SRID=4326;') and reject unsupported extended types upstream.
  3. For unsupported geometry types, convert to a supported equivalent (e.g. triangulate TINs, sample curves) before serialization.
  4. 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

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


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