elastic/elasticsearch · error · IllegalArgumentException
When specifying 'Z' or 'M', coordinates must include three v
Error message
When specifying 'Z' or 'M', coordinates must include three values. Only two coordinates were provided
What it means
Thrown by WellKnownText.checkZorMAttribute after a geometry is parsed. If the WKT explicitly specified a 'Z' or 'M' qualifier on the type keyword (e.g. "POINT Z (...)" or "POINTM (...)"), but the parsed geometry's hasZ() returns false (coordinates only had 2 values), the qualifier promised a third dimension that was not delivered.
Source
Thrown at libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownText.java:470
case "point" -> parsePoint(stream);
case "multipoint" -> parseMultiPoint(stream);
case "linestring" -> parseLine(stream);
case "multilinestring" -> parseMultiLine(stream);
case "polygon" -> parsePolygon(stream, coerce);
case "multipolygon" -> parseMultiPolygon(stream, coerce);
case "bbox" -> parseBBox(stream);
case "geometrycollection" -> parseGeometryCollection(stream, coerce, depth + 1);
case "circle" -> // Not part of the standard, but we need it for internal serialization
parseCircle(stream);
default -> throw new IllegalArgumentException("Unknown geometry type: " + type);
};
checkZorMAttribute(isExplicitlySpecifiesZorM, geometry.hasZ());
return geometry;
}
static void checkZorMAttribute(boolean isExplicitlySpecifiesZorM, boolean hasZ) {
if (isExplicitlySpecifiesZorM && hasZ == false) {
throw new IllegalArgumentException(
"When specifying 'Z' or 'M', coordinates must include three values. Only two coordinates were provided"
);
}
}
private static GeometryCollection<Geometry> parseGeometryCollection(StreamTokenizer stream, boolean coerce, int depth)
throws IOException, ParseException {
if (nextEmptyOrOpen(stream).equals(EMPTY)) {
return GeometryCollection.EMPTY;
}
if (depth > MAX_NESTED_DEPTH) {
throw new ParseException("maximum nested depth of " + MAX_NESTED_DEPTH + " exceeded", stream.lineno());
}
List<Geometry> shapes = new ArrayList<>();
shapes.add(parseGeometry(stream, coerce, depth));
while (nextCloserOrComma(stream).equals(COMMA)) {
shapes.add(parseGeometry(stream, coerce, depth));
}View on GitHub (pinned to db6a809a66)
Solutions
- Either supply the third coordinate value for every tuple so geometry.hasZ() is true: "POINT Z (1 2 3)".
- Or remove the Z/M qualifier if the data is genuinely 2D: "POINT (1 2)".
- Ensure consistency: every coordinate tuple in the geometry must have the same dimensionality as the qualifier declares.
Example fix
// before: Z qualifier but only 2 coordinates
Geometry g = WellKnownText.fromWKT("POINT Z (1 2)");
// after: provide the Z value
Geometry g = WellKnownText.fromWKT("POINT Z (1 2 3)");
// or drop the qualifier for 2D data
Geometry g = WellKnownText.fromWKT("POINT (1 2)"); Defensive patterns
Strategy: validation
Validate before calling
// Ensure Z qualifier matches coordinate arity before parsing
static void validateZConsistency(String wkt) {
String upper = wkt.toUpperCase(Locale.ROOT);
boolean hasQualifier = upper.contains(" Z") || upper.contains(" Z(") || upper.contains("M(") || upper.matches("(?i).*\\bZ\\b.*\\(.*\\).*");
if (hasQualifier) {
// every coordinate tuple must have 3 components; do a quick count
// (full validation is done by the parser, this is a pre-check)
}
} Try / catch
try {
Geometry g = WellKnownText.fromWKT(wkt);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Z")) {
// prompt user to add the third coordinate or drop the qualifier
}
throw e;
} Prevention
- Keep Z/M qualifiers consistent with the coordinate arity in source data.
- If the dataset is 2D, omit the qualifier entirely.
- Normalize source tuples to uniform dimensionality before WKT generation.
When it happens
Trigger: WKT input of the form "POINT Z (1 2)" or "LINESTRING M (0 0, 1 1)" where the qualifier declares Z/M but the coordinate tuples contain only two numbers. The parser reads the Z/M token, sets isExplicitlySpecifiesZorM=true, then parsePoint/parseLine reads only lon and lat (no third number), so geometry.hasZ() is false and checkZorMAttribute throws.
Common situations: Hand-authored or generated WKT where the Z qualifier was added for documentation but coordinates were left 2D; mixed-up serialization from a tool that emits the qualifier header but trims the third coordinate; copy-paste from a 3D dataset with the altitude column dropped.
Related errors
- coordinate dimensions do not match: {}
- maximum nested depth of 1000 exceeded
- expected word but found: {}
- invalid number found: {}
- expected number but found: {}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/6ed29665ffba1588.
Report an issue: GitHub.