{"record":{"id":"ca51618d2757ef4e","repo":"elastic/elasticsearch","slug":"empty","errorCode":null,"errorMessage":"Empty ","messagePattern":"Empty ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownBinary.java","lineNumber":65,"sourceCode":"     * Converts the given {@link Geometry} to WKB with the provided {@link ByteOrder}\n     */\n    public static byte[] toWKB(Geometry geometry, ByteOrder byteOrder) {\n        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {\n            toWKB(geometry, outputStream, ByteBuffer.allocate(8).order(byteOrder));\n            return outputStream.toByteArray();\n        } catch (IOException ioe) {\n            // Should never happen as the only method throwing IOException is ByteArrayOutputStream#close and it is a NOOP\n            throw new UncheckedIOException(ioe);\n        }\n    }\n\n    private static void toWKB(Geometry geometry, ByteArrayOutputStream out, ByteBuffer scratch) {\n        out.write(scratch.order() == ByteOrder.BIG_ENDIAN ? 0 : 1);\n        geometry.visit(new GeometryVisitor<Void, RuntimeException>() {\n            @Override\n            public Void visit(Point point) {\n                if (point.isEmpty()) {\n                    throw new IllegalArgumentException(\"Empty \" + point.type() + \" cannot be represented in WKB\");\n                }\n                writeInt(out, scratch, point.hasZ() ? 1001 : 1);\n                writeDouble(out, scratch, point.getX());\n                writeDouble(out, scratch, point.getY());\n                if (point.hasZ()) {\n                    writeDouble(out, scratch, point.getZ());\n                }\n                return null;\n            }\n\n            @Override\n            public Void visit(Line line) {\n                writeInt(out, scratch, line.hasZ() ? 1002 : 2);\n                writeInt(out, scratch, line.length());\n                for (int i = 0; i < line.length(); ++i) {\n                    writeDouble(out, scratch, line.getX(i));\n                    writeDouble(out, scratch, line.getY(i));\n                    if (line.hasZ()) {","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownBinary.java#L47-L83","documentation":"WellKnownBinary.toWKB serializes a Geometry into the OGC WKB binary format. The Point visitor (line 63) throws IllegalArgumentException when point.isEmpty() is true, because the WKB format has no representation for an empty Point (unlike empty Polygon/Line which serialize as zero-length). This is a format limitation: WKB requires at least one coordinate pair for a Point.","triggerScenarios":"Calling WellKnownBinary.toWKB(Point.EMPTY, byteOrder), WellKnownBinary.toWKB(new Point(...).emptyVariant(), ...) or passing any Point whose isEmpty() returns true. Also triggered indirectly when serializing a MultiPoint/GeometryCollection that contains an empty Point child (line 110/140 recurse into toWKB for each child).","commonSituations":"Storing or transmitting optional-location fields where absence was modeled as Point.EMPTY rather than null. Round-tripping GeoJSON that used 'coordinates':[] to represent missing point data. Aggregation pipelines that produce empty points (e.g. centroid of zero-input set) and then attempt WKB serialization for storage/transport.","solutions":["Guard before serialization: if (point.isEmpty()) skip or substitute a sentinel, since WKB cannot encode it.","Represent absence with Java null (or an Optional<Point>) in your data model instead of Point.EMPTY when the downstream sink is WKB.","If you control ingestion, normalize empty points to a concrete coordinate (e.g. the field default/centroid) or drop the document.","When serializing collections, filter out empty Point children before toWKB to avoid the throw at the child level."],"exampleFix":"// before\nbyte[] wkb = WellKnownBinary.toWKB(point, ByteOrder.LITTLE_ENDIAN); // throws on Point.EMPTY\n\n// after\nif (point.isEmpty()) {\n    return null; // or skip / use sentinel\n}\nbyte[] wkb = WellKnownBinary.toWKB(point, ByteOrder.LITTLE_ENDIAN);","handlingStrategy":"validation","validationCode":"boolean canSerializeAsWKB(Geometry g) {\n    if (g instanceof Point p && p.isEmpty()) return false;\n    if (g instanceof Circle c && c.isEmpty()) return false;\n    if (g instanceof Rectangle r && r.isEmpty()) return false;\n    if (g instanceof LinearRing) return false;\n    if (g instanceof GeometryCollection<?> col) {\n        for (Geometry child : col) if (!canSerializeAsWKB(child)) return false;\n    }\n    return true;\n}","typeGuard":"static boolean isEmptyPoint(Geometry g) { return g instanceof Point p && p.isEmpty(); }","tryCatchPattern":"try {\n    return WellKnownBinary.toWKB(point, bo);\n} catch (IllegalArgumentException e) {\n    if (point.isEmpty()) return null; // absent data\n    throw e;\n}","preventionTips":["Model optional/absent point data as null rather than Point.EMPTY when the sink is WKB.","Filter empty geometries out of collections before serialization.","Add a serialization pre-check helper used uniformly at all WKB emit sites."],"tags":["geo","wkb","serialization","point","empty","elasticsearch"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}