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

  1. Gate child computation with H3.getResolution(h3) < H3.MAX_H3_RES before calling childPosToH3 or h3ToChildren.
  2. Treat res-15 cells as leaves in any recursive subdivision.
  3. 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

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


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/6e435d13fc04eff2. Report an issue: GitHub.