elastic/elasticsearch · error · IllegalArgumentException
Resolution overflow
Error message
Resolution overflow
What it means
Thrown by H3.childPosToH3 when the input index is already at MAX_H3_RES (15). Computing a child requires resolution+1; 15+1 exceeds the maximum, so no child can exist. The string overload propagates the same exception.
Source
Thrown at libs/h3/src/main/java/org/elasticsearch/h3/H3.java:264
}
return children;
}
/**
* Transforms a list of H3 indexes in long form to a list of H3
* indexes in string form.
*/
public static String[] h3ToChildren(String h3Address) {
return h3ToStringList(h3ToChildren(stringToH3(h3Address)));
}
/**
* Returns the child cell at the given position
*/
public static long childPosToH3(long h3, int childPos) {
final int childrenRes = H3Index.H3_get_resolution(h3) + 1;
if (childrenRes > MAX_H3_RES) {
throw new IllegalArgumentException("Resolution overflow");
}
final long childH = H3Index.H3_set_resolution(h3, childrenRes);
if (childPos == 0) {
return H3Index.H3_set_index_digit(childH, childrenRes, CoordIJK.Direction.CENTER_DIGIT.digit());
}
final boolean isPentagon = isPentagon(h3);
final int maxPos = isPentagon ? 5 : 6;
if (childPos < 0 || childPos > maxPos) {
throw new IllegalArgumentException("invalid child position");
}
if (isPentagon) {
// Pentagon skip digit (position) is the number 1, therefore we add one
// to the current position.
return H3Index.H3_set_index_digit(childH, childrenRes, childPos + 1);
} else {
return H3Index.H3_set_index_digit(childH, childrenRes, childPos);
}
}View on GitHub (pinned to db6a809a66)
Solutions
- Gate child computation with H3.getResolution(h3) < H3.MAX_H3_RES before calling childPosToH3 or h3ToChildren.
- Treat res-15 cells as leaves in any recursive subdivision.
- Use h3ToChildrenSize(h3) first (which throws Invalid child resolution at res 15) only after the resolution check, to size outputs.
Example fix
// before
long[] kids = H3.h3ToChildren(cell); // throws Resolution overflow if cell is res 15
// after
long[] kids = H3.getResolution(cell) < H3.MAX_H3_RES
? H3.h3ToChildren(cell)
: new long[0]; Defensive patterns
Strategy: validation
Validate before calling
static boolean canRefine(long h3) {
return org.elasticsearch.h3.H3.getResolution(h3) < org.elasticsearch.h3.H3.MAX_H3_RES;
}
static long[] safeChildren(long h3) {
return canRefine(h3) ? org.elasticsearch.h3.H3.h3ToChildren(h3) : new long[0];
} Type guard
static boolean isRefinable(long h3) {
return org.elasticsearch.h3.H3.getResolution(h3) < org.elasticsearch.h3.H3.MAX_H3_RES;
} Try / catch
try {
return H3.childPosToH3(h3, pos);
} catch (IllegalArgumentException e) {
if (e.getMessage().equals("Resolution overflow")) return -1; // leaf
throw e;
} Prevention
- Gate every refine/children call with getResolution < MAX_H3_RES.
- Make res-15 a leaf in recursive subdivision.
- Centralize the resolution guard so child-count and child-iteration share it.
When it happens
Trigger: Calling childPosToH3(cell, pos) (or h3ToChildren/h3ToChildren(address) which call it internally) on a res-15 index. Also reached via H3.hexRing -> hexRingPosToH3 path indirectly when chained incorrectly.
Common situations: General-purpose code that unconditionally subdivides cells without checking the current resolution; consuming res-15 fine-grained cells and trying to refine them further; recursive algorithms lacking a res-15 base case.
Related errors
- Invalid child resolution [{}]
- Input is a base cell
- invalid child position
- resolution [{}] is out of range (must be 0 <= res <= 15)
- time value cannot store values greater than 106751 days
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/6e435d13fc04eff2.
Report an issue: GitHub.