{"record":{"id":"1eca00903fd78336","repo":"elastic/elasticsearch","slug":"maximum-nested-depth-of-1000-exceeded","errorCode":null,"errorMessage":"maximum nested depth of 1000 exceeded","messagePattern":"maximum nested depth of 1000 exceeded","errorType":"validation","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownText.java","lineNumber":482,"sourceCode":"        checkZorMAttribute(isExplicitlySpecifiesZorM, geometry.hasZ());\n        return geometry;\n    }\n\n    static void checkZorMAttribute(boolean isExplicitlySpecifiesZorM, boolean hasZ) {\n        if (isExplicitlySpecifiesZorM && hasZ == false) {\n            throw new IllegalArgumentException(\n                \"When specifying 'Z' or 'M', coordinates must include three values. Only two coordinates were provided\"\n            );\n        }\n    }\n\n    private static GeometryCollection<Geometry> parseGeometryCollection(StreamTokenizer stream, boolean coerce, int depth)\n        throws IOException, ParseException {\n        if (nextEmptyOrOpen(stream).equals(EMPTY)) {\n            return GeometryCollection.EMPTY;\n        }\n        if (depth > MAX_NESTED_DEPTH) {\n            throw new ParseException(\"maximum nested depth of \" + MAX_NESTED_DEPTH + \" exceeded\", stream.lineno());\n        }\n        List<Geometry> shapes = new ArrayList<>();\n        shapes.add(parseGeometry(stream, coerce, depth));\n        while (nextCloserOrComma(stream).equals(COMMA)) {\n            shapes.add(parseGeometry(stream, coerce, depth));\n        }\n        return new GeometryCollection<>(shapes);\n    }\n\n    private static Point parsePoint(StreamTokenizer stream) throws IOException, ParseException {\n        if (nextEmptyOrOpen(stream).equals(EMPTY)) {\n            return Point.EMPTY;\n        }\n        double lon = nextNumber(stream);\n        double lat = nextNumber(stream);\n        Point pt;\n        if (isNumberNext(stream)) {\n            pt = new Point(lon, lat, nextNumber(stream));","sourceCodeStart":464,"sourceCodeEnd":500,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownText.java#L464-L500","documentation":"Thrown by WellKnownText.parseGeometryCollection when the recursion depth exceeds MAX_NESTED_DEPTH (1000). Each nested GEOMETRYCOLLECTION increments the depth counter passed to parseGeometry; this guards the recursive descent against unbounded input.","triggerScenarios":"Parsing a WKT string with more than 1000 levels of nested GEOMETRYCOLLECTION, e.g. \"GEOMETRYCOLLECTION (GEOMETRYCOLLECTION (GEOMETRYCOLLECTION ( ... )))\" deeper than 1000. Also reachable if the depth parameter is misused by a caller invoking the package-private parseGeometry directly with a large starting depth.","commonSituations":"Adversarial or fuzzed input designed to cause stack exhaustion; generated test fixtures with runaway nesting; a serialization bug that emits redundant wrapping collections.","solutions":["Flatten or reduce the nesting depth of the input geometry collection to <= 1000 levels.","If the deep nesting is legitimate (unlikely), pre-validate by counting GEOMETRYCOLLECTION tokens and reject upstream with a clearer message.","Sanitize untrusted WKT before parsing to cap collection nesting."],"exampleFix":"// before: deeply nested collection from untrusted source\nString wkt = maliciousInput; // GEOMETRYCOLLECTION nested 5000 deep\nGeometry g = WellKnownText.fromWKT(wkt);\n\n// after: cap nesting before parsing\nlong depth = wkt.chars().filter(c -> c == '(').count();\nif (depth > 1000) {\n    throw new IllegalArgumentException(\"WKT nesting too deep: \" + depth);\n}\nGeometry g = WellKnownText.fromWKT(wkt);","handlingStrategy":"validation","validationCode":"static void checkNestingDepth(String wkt) {\n    int depth = 0, max = 0;\n    for (int i = 0; i < wkt.length(); i++) {\n        char c = wkt.charAt(i);\n        if (c == '(') { depth++; max = Math.max(max, depth); }\n        else if (c == ')') depth--;\n    }\n    if (max > 1000) {\n        throw new IllegalArgumentException(\"WKT nesting depth \" + max + \" exceeds limit 1000\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    Geometry g = WellKnownText.fromWKT(wkt);\n} catch (java.text.ParseException e) {\n    if (e.getMessage().contains(\"nested depth\")) {\n        // reject input as too deeply nested\n    }\n    throw e;\n}","preventionTips":["Cap collection nesting for untrusted WKT before parsing.","Count open-paren depth as a cheap pre-validation.","Flatten generated collections that wrap redundantly."],"tags":["geo","wkt","parsing","elasticsearch","geometry","dos-protection"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}