{"record":{"id":"7d7a1afb2b282a2f","repo":"elastic/elasticsearch","slug":"found-z-value-7d7a1a","errorCode":null,"errorMessage":"found Z value [","messagePattern":"found Z value \\[","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/geo/src/main/java/org/elasticsearch/geometry/utils/StandardValidator.java","lineNumber":50,"sourceCode":" */\npublic class StandardValidator implements GeometryValidator {\n\n    private static final GeometryValidator TRUE = new StandardValidator(true);\n    private static final GeometryValidator FALSE = new StandardValidator(false);\n\n    private final boolean ignoreZValue;\n\n    private StandardValidator(boolean ignoreZValue) {\n        this.ignoreZValue = ignoreZValue;\n    }\n\n    public static GeometryValidator instance(boolean ignoreZValue) {\n        return ignoreZValue ? TRUE : FALSE;\n    }\n\n    protected void checkZ(double zValue) {\n        if (ignoreZValue == false && Double.isNaN(zValue) == false) {\n            throw new IllegalArgumentException(\"found Z value [\" + zValue + \"] but [ignore_z_value] parameter is [\" + ignoreZValue + \"]\");\n        }\n    }\n\n    @Override\n    public void validateCoordinate(double x, double y, double z) {\n        checkZ(z);\n    }\n\n    @Override\n    public void validate(Geometry geometry) {\n        if (ignoreZValue == false) {\n            geometry.visit(new GeometryVisitor<Void, RuntimeException>() {\n\n                @Override\n                public Void visit(Circle circle) throws RuntimeException {\n                    checkZ(circle.getZ());\n                    return null;\n                }","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/geo/src/main/java/org/elasticsearch/geometry/utils/StandardValidator.java#L32-L68","documentation":"StandardValidator.checkZ (line 48) throws IllegalArgumentException when ignoreZValue is false AND the supplied z is not NaN. The validator is the CRS-agnostic default used by both geo_shape and shape parsing (see class Javadoc). It exists to enforce that a field mapping configured with ignore_z_value=false rejects 3D coordinates. The shared TRUE/FALSE singletons (lines 35-36) mean instance(true) silently drops Z, instance(false) strictly rejects it.","triggerScenarios":"Parsing or validating a geometry that carries a non-NaN Z (altitude) value when the field mapping set ignore_z_value=false. Reached via StandardValidator.validateCoordinate(x,y,z) (line 55), via StandardValidator.validate(geometry) which walks every coordinate (lines 60-130), or indirectly through WellKnownText.fromWKT / WellKnownBinary.fromWKB / fromWKT which call validator.validateCoordinate per parsed ordinate. Also triggered by GeometryParser-based REST ingestion when the geo_shape/shape mapping has ignore_z_value disabled.","commonSituations":"Indexing 3D GeoJSON (coordinates with altitude) into a geo_shape field whose mapping omits or disables ignore_z_value. Switching a field mapping from ignore_z_value=true to false on an index that already contains 3D data (revalidation on reindex). Copying WKT like 'POINT Z(1 2 3)' or 'POINT(1 2 3)' into a 2D-only field. Third-party feeds (aviation, IoT altitude sensors) emitting 3D points into a strict 2D mapping.","solutions":["Update the field mapping to set \"ignore_z_value\": true so 3D ordinates are accepted but ignored — the most common intended behavior.","Strip the Z component from incoming coordinates before indexing (project to 2D in your ingestion pipeline / ingest processor).","If 3D data is legitimate, remap the field with a method that preserves Z (e.g. geo_shape with ignore_z_value=true) rather than forcing 2D.","For programmatic parsing, pass StandardValidator.instance(true) (or GeometryValidator.NOOP) to fromWKT/fromWKB when you do not want Z enforcement."],"exampleFix":"// before — strict 2D, rejects altitude\nGeometryValidator v = StandardValidator.instance(false);\nv.validateCoordinate(lon, lat, alt); // throws if alt present\n\n// after — accept and ignore altitude\nGeometryValidator v = StandardValidator.instance(true);\nv.validateCoordinate(lon, lat, alt); // ok, alt dropped","handlingStrategy":"validation","validationCode":"GeometryValidator chooseValidator(boolean ignoreZ, Geometry g) {\n    if (ignoreZ) return StandardValidator.instance(true);\n    // pre-check: does the geometry carry Z?\n    if (geometryHasZ(g)) {\n        throw new IllegalArgumentException(\"mapping rejects Z values; got 3D geometry\");\n    }\n    return StandardValidator.instance(false);\n}","typeGuard":"// hasZ is exposed on Geometry; for collections, recurse\nboolean geometryHasZ(Geometry g) {\n    if (g.hasZ()) return true;\n    if (g instanceof GeometryCollection<?> c) {\n        for (Geometry child : c) if (geometryHasZ(child)) return true;\n    }\n    return false;\n}","tryCatchPattern":"try {\n    validator.validateCoordinate(x, y, z);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"found Z value\")) {\n        // strip Z and retry, or surface a mapping-config error to the user\n    } else throw e;\n}","preventionTips":["Align the field mapping's ignore_z_value with the dimensionality of incoming data.","Default new geo_shape/shape mappings to ignore_z_value=true unless 2D-strictness is a documented requirement.","Audit ingest feeds for 3D coordinates before turning strictness on."],"tags":["geo","geometry","z-value","validator","mapping","elasticsearch"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}