elastic/elasticsearch · error · IllegalArgumentException

Linear ring is not supported by WKT

Error message

Linear ring is not supported by WKT

What it means

WellKnownText.toWKT's visitor has a visit(LinearRing) override (line 114) that unconditionally throws IllegalArgumentException. LinearRing is not a standalone WKT type — WKT has no LINEARRING keyword. A LinearRing only exists structurally inside a Polygon (whose visitor at line 185 casts its ring to Line for output). A bare LinearRing reaching the top-level toWKT visitor is a caller bug.

Source

Thrown at libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownText.java:115

                    return null;
                }

                @Override
                public Void visit(Line line) {
                    sb.append(LPAREN);
                    visitPoint(line.getX(0), line.getY(0), line.getZ(0));
                    for (int i = 1; i < line.length(); ++i) {
                        sb.append(COMMA);
                        sb.append(SPACE);
                        visitPoint(line.getX(i), line.getY(i), line.getZ(i));
                    }
                    sb.append(RPAREN);
                    return null;
                }

                @Override
                public Void visit(LinearRing ring) {
                    throw new IllegalArgumentException("Linear ring is not supported by WKT");
                }

                @Override
                public Void visit(MultiLine multiLine) {
                    visitCollection(multiLine);
                    return null;
                }

                @Override
                public Void visit(MultiPoint multiPoint) {
                    if (multiPoint.isEmpty()) {
                        sb.append(EMPTY);
                        return null;
                    }
                    // walk through coordinates:
                    sb.append(LPAREN);
                    visitPoint(multiPoint.get(0).getX(), multiPoint.get(0).getY(), multiPoint.get(0).getZ());
                    for (int i = 1; i < multiPoint.size(); ++i) {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Wrap the LinearRing in a Polygon before serializing: new Polygon(shell) or new Polygon(shell, holes).
  2. Always pass the Polygon (which contains the ring) to toWKT, never a bare LinearRing.
  3. If you have a bare ring you truly need as a linestring in text, construct a Line from the ring's coordinates and serialize that.

Example fix

// before
LinearRing shell = new LinearRing(new double[]{0,1,1,0}, new double[]{0,0,1,0});
String wkt = WellKnownText.toWKT(shell); // throws: Linear ring is not supported by WKT

// after — wrap in a Polygon
Polygon polygon = new Polygon(shell);
String wkt = WellKnownText.toWKT(polygon); // "POLYGON ((0.0 0.0, 1.0 0.0, ...))"
Defensive patterns

Strategy: type-guard

Validate before calling

Geometry ensureNotBareRing(Geometry g) {
    if (g instanceof LinearRing r) return new Polygon(r);
    return g;
}

Type guard

static boolean isBareLinearRing(Geometry g) { return g instanceof LinearRing; }

Try / catch

try {
    return WellKnownText.toWKT(g);
} catch (IllegalArgumentException | UnsupportedOperationException e) {
    if (g instanceof LinearRing r) return WellKnownText.toWKT(new Polygon(r));
    throw e;
}

Prevention

When it happens

Trigger: Calling WellKnownText.toWKT(linearRing) where the argument is a standalone LinearRing. Constructing a Polygon manually but passing the ring (polygon.getPolygon()) to toWKT instead of the Polygon. Note: getWKTName (line 801) throws a different UnsupportedOperationException for LinearRing, so the toWKT entry path may fail earlier at naming rather than at visit.

Common situations: Custom geometry builders that assemble rings then serialize the ring directly. Refactoring that mis-routes a ring to the top-level serializer. Misuse of the public toWKT API with internally-typed objects. Confusing LinearRing (structural) with Line (serializable).

Related errors


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