{"record":{"id":"df25078e143187a2","repo":"elastic/elasticsearch","slug":"resolution-is-out-of-range-must-be-0-res","errorCode":null,"errorMessage":"resolution [{}]  is out of range (must be 0 <= res <= 15)","messagePattern":"resolution \\[(.+?)\\]  is out of range \\(must be 0 <= res <= 15\\)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/h3/src/main/java/org/elasticsearch/h3/H3.java","lineNumber":607,"sourceCode":"                result *= base;\n            }\n            exp >>= 1;\n            base *= base;\n        }\n\n        return result;\n    }\n\n    private static String[] h3ToStringList(long[] h3s) {\n        return Arrays.stream(h3s).mapToObj(H3::h3ToString).toArray(String[]::new);\n    }\n\n    /**\n     * @throws IllegalArgumentException <code>res</code> is not a valid H3 resolution.\n     */\n    private static void checkResolution(int res) {\n        if (res < 0 || res > MAX_H3_RES) {\n            throw new IllegalArgumentException(\"resolution [\" + res + \"]  is out of range (must be 0 <= res <= 15)\");\n        }\n    }\n}\n","sourceCodeStart":589,"sourceCodeEnd":611,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/h3/src/main/java/org/elasticsearch/h3/H3.java#L589-L611","documentation":"Thrown by H3's private checkResolution, invoked by geoToH3/geoToH3Address, northPolarH3, and southPolarH3 when res is not in [0, MAX_H3_RES] (0..15). The resolution selects which H3 grid level to use; values outside this band have no defined grid.","triggerScenarios":"Calling H3.geoToH3(lat, lng, res), geoToH3Address, northPolarH3(res), or southPolarH3(res) with res < 0 or res > 15. The most common entry point is geoToH3 with an unvalidated user resolution.","commonSituations":"User-supplied precision/zoom parameter passed straight to geoToH3 without clamping; default value left as -1 or 0 sentinel; confusion with a different library's resolution scale (e.g. 0..28 elsewhere).","solutions":["Clamp/validate res to [0, H3.MAX_H3_RES] before calling any geoToH3/polar method.","Use H3.MAX_H3_RES constant (15) rather than a magic number so version changes propagate.","Return a clear upstream error for out-of-range user input instead of letting the library throw the generic message."],"exampleFix":"// before\nlong cell = H3.geoToH3(lat, lng, userPrecision); // throws if userPrecision is 16 or -1\n\n// after\nint res = Math.max(0, Math.min(H3.MAX_H3_RES, userPrecision));\nlong cell = H3.geoToH3(lat, lng, res);","handlingStrategy":"validation","validationCode":"static long safeGeoToH3(double lat, double lng, int res) {\n    if (res < 0 || res > org.elasticsearch.h3.H3.MAX_H3_RES) {\n        throw new IllegalArgumentException(\n            \"res \" + res + \" out of [0, \" + org.elasticsearch.h3.H3.MAX_H3_RES + \"]\");\n    }\n    return org.elasticsearch.h3.H3.geoToH3(lat, lng, res);\n}","typeGuard":"static boolean validResolution(int res) {\n    return res >= 0 && res <= org.elasticsearch.h3.H3.MAX_H3_RES;\n}","tryCatchPattern":"try {\n    return H3.geoToH3(lat, lng, res);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"is out of range\")) {\n        throw new IllegalArgumentException(\"bad resolution \" + res, e);\n    }\n    throw e;\n}","preventionTips":["Clamp user-supplied precision to [0, H3.MAX_H3_RES] before calling.","Reference MAX_H3_RES, not a literal 15, so version changes propagate.","Reject out-of-range resolutions at the API boundary with a clear error."],"tags":["h3","resolution","validation","geo"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}