{"record":{"id":"afc90d1fb7f41be8","repo":"elastic/elasticsearch","slug":"unknown-geometry-type","errorCode":null,"errorMessage":"Unknown geometry type: ","messagePattern":"Unknown geometry type: ","errorType":"validation","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownBinary.java","lineNumber":270,"sourceCode":"        ByteBuffer scratch,\n        boolean coerce,\n        int depth,\n        GeometryValidator validator\n    ) throws IOException, ParseException {\n        final String type = WellKnownText.nextWord(stream).toLowerCase(Locale.ROOT);\n        final boolean explicitZ = WellKnownText.isZOrMNext(stream);\n        out.write(scratch.order() == ByteOrder.BIG_ENDIAN ? 0 : 1);\n        switch (type) {\n            case \"point\" -> writeWKBPoint(stream, out, scratch, explicitZ, validator);\n            case \"multipoint\" -> writeWKBMultiPoint(stream, out, scratch, explicitZ, validator);\n            case \"linestring\" -> writeWKBLineString(stream, out, scratch, explicitZ, validator);\n            case \"multilinestring\" -> writeWKBMultiLineString(stream, out, scratch, explicitZ, validator);\n            case \"polygon\" -> writeWKBPolygon(stream, out, scratch, coerce, explicitZ, validator);\n            case \"multipolygon\" -> writeWKBMultiPolygon(stream, out, scratch, coerce, explicitZ, validator);\n            case \"geometrycollection\" -> writeWKBGeometryCollection(stream, out, scratch, coerce, depth, explicitZ, validator);\n            case \"circle\" -> writeWKBCircle(stream, out, scratch, explicitZ, validator);\n            case \"bbox\" -> writeWKBBBox(stream, out, scratch, explicitZ, validator);\n            default -> throw new ParseException(\"Unknown geometry type: \" + type, stream.lineno());\n        }\n    }\n\n    private static void writeWKBPoint(\n        StreamTokenizer stream,\n        ByteArrayOutputStream out,\n        ByteBuffer scratch,\n        boolean explicitZ,\n        GeometryValidator validator\n    ) throws IOException, ParseException {\n        if (WellKnownText.nextEmptyOrOpen(stream).equals(WellKnownText.EMPTY)) {\n            throw new IllegalArgumentException(\"Empty POINT cannot be represented in WKB\");\n        }\n        double x = WellKnownText.nextNumber(stream);\n        double y = WellKnownText.nextNumber(stream);\n        double z = Double.NaN;\n        if (WellKnownText.isNumberNext(stream)) {\n            z = WellKnownText.nextNumber(stream);","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownBinary.java#L252-L288","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nbyte[] wkb = WellKnownBinary.fromWKT(\"TRIANGLE((0 0, 1 0, 0 1, 0 0))\", ByteOrder.LITTLE_ENDIAN, false);\n// throws: Unknown geometry type: triangle\n\n// after — convert to a supported type (Polygon) first\nString wkt = \"POLYGON((0 0, 1 0, 0 1, 0 0))\";\nbyte[] wkb = WellKnownBinary.fromWKT(wkt, ByteOrder.LITTLE_ENDIAN, false);","handlingStrategy":"validation","validationCode":"static final Set<String> WKB_WKT_TYPES = Set.of(\n    \"point\",\"multipoint\",\"linestring\",\"multilinestring\",\n    \"polygon\",\"multipolygon\",\"geometrycollection\",\"circle\",\"bbox\");\nboolean isSupportedWktType(String wkt) {\n    String head = wkt.trim().split(\"[\\\\s(]\", 2)[0].toLowerCase(Locale.ROOT);\n    return WKB_WKT_TYPES.contains(head);\n}","typeGuard":"static String headType(String wkt) {\n    String t = wkt.trim().split(\"[\\\\s(]\", 2)[0];\n    return t == null ? \"\" : t.toLowerCase(Locale.ROOT);\n}","tryCatchPattern":"try {\n    return WellKnownBinary.fromWKT(wkt, bo, coerce, v);\n} catch (ParseException e) {\n    if (e.getMessage().startsWith(\"Unknown geometry type\")) {\n        throw new IllegalArgumentException(\"Unsupported WKT type in input\", e);\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["geo","wkt","wkb","parsing","unknown-type","elasticsearch"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}