elastic/elasticsearch · error · IllegalArgumentException
holes must have the same number of dimensions as the polygon
Error message
holes must have the same number of dimensions as the polygon
What it means
writeWKBPolygon (line 321) reads the outer ring and any holes from WKT, then at lines 341-345 verifies every ring has the same Z dimensionality as the first (outer) ring. If any hole's hasZ differs from the shell's hasZ, it throws IllegalArgumentException. WKB polygon encoding (type 3 or 1003) is single-dimensionality per geometry — a polygon cannot mix 2D and 3D rings.
Source
Thrown at libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownBinary.java:344
boolean explicitZ,
GeometryValidator validator
) throws IOException, ParseException {
if (WellKnownText.nextEmptyOrOpen(stream).equals(WellKnownText.EMPTY)) {
writeInt(out, scratch, 3);
writeInt(out, scratch, 0);
return;
}
List<CoordsList> rings = new ArrayList<>();
WellKnownText.nextOpener(stream);
rings.add(wktReadRing(stream, coerce, validator));
while (WellKnownText.nextCloserOrComma(stream).equals(WellKnownText.COMMA)) {
WellKnownText.nextOpener(stream);
rings.add(wktReadRing(stream, coerce, validator));
}
boolean hasZ = rings.isEmpty() == false && rings.get(0).hasZ();
for (CoordsList ring : rings) {
if (ring.hasZ() != hasZ) {
throw new IllegalArgumentException("holes must have the same number of dimensions as the polygon");
}
}
WellKnownText.checkZorMAttribute(explicitZ, hasZ);
writeInt(out, scratch, hasZ ? 1003 : 3);
writeInt(out, scratch, rings.size());
for (CoordsList ring : rings) {
writeInt(out, scratch, ring.size());
writeCoordinateList(out, scratch, ring);
}
}
private static void writeWKBMultiPoint(
StreamTokenizer stream,
ByteArrayOutputStream out,
ByteBuffer scratch,
boolean explicitZ,
GeometryValidator validator
) throws IOException, ParseException {View on GitHub (pinned to db6a809a66)
Solutions
- Make dimensionality consistent across all rings of the polygon: either add Z to every ring or remove Z from every ring.
- Validate before serialization: parse the WKT, check each ring's Z presence, and normalize (strip Z or backfill) before fromWKT.
- Configure your authoring tool to enforce uniform dimensionality per polygon.
Example fix
// before — mixed dimensions
fromWKT("POLYGON((0 0, 10 0, 10 10, 0 0), (1 1 5, 2 1 5, 2 2 5, 1 1 5))", BO, false, v);
// throws: holes must have the same number of dimensions as the polygon
// after — all rings 2D
fromWKT("POLYGON((0 0, 10 0, 10 10, 0 0), (1 1, 2 1, 2 2, 1 1))", BO, false, v); Defensive patterns
Strategy: validation
Validate before calling
// after parsing rings into CoordsList-like structures:
boolean ringsConsistentZ(List<boolean> ringHasZ) {
Boolean first = null;
for (boolean z : ringHasZ) {
if (first == null) first = z;
else if (z != first) return false;
}
return true;
} Type guard
// structural: confirm outer and all holes share hasZ before fromWKT
static boolean polygonRingsUniformZ(String wkt) {
// crude check: count Z triples vs pairs per ring; better: parse to Geometry first
return true; // implement per-ring Z-presence scan
} Try / catch
try {
return WellKnownBinary.fromWKT(wkt, bo, coerce, v);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("holes must have the same number of dimensions")) {
// normalize: strip Z from all rings, then retry
} else throw e;
} Prevention
- Enforce uniform per-polygon dimensionality in authoring/import tools.
- Pre-validate ring Z presence and normalize (strip or backfill) before fromWKT.
- Reject mixed-dimension polygons at the API boundary with a clear error.
When it happens
Trigger: Calling WellKnownBinary.fromWKT with a POLYGON WKT whose outer ring and hole(s) disagree on Z presence, e.g. outer 'POLYGON((0 0, 10 0, 10 10, 0 0), (1 1 5, 2 1 5, 2 2 5, 1 1 5))' (outer 2D, hole 3D) or the reverse. Reached during direct WKT-to-WKB conversion.
Common situations: Hand-authored WKT where the author added altitude to holes but not the shell (or vice versa). Merging polygon data from sources with inconsistent dimensionality. Edit tools that append Z to selected rings. Programmatic polygon builders that conditionally add Z per-ring.
Related errors
- all elements of the collection should have the same number o
- Linear ring is not supported by WKB
- Unknown geometry type:
- Empty POINT cannot be represented in WKB
- maximum nested depth of
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/6fb5e0bf3f17ae7e.
Report an issue: GitHub.