pinpoint-apm/pinpoint · error · IllegalArgumentException

numRegions must be greater than 1

Error message

numRegions must be greater than 1

What it means

The Auto SplitOption requires numRegions > 1 because auto-splitting uses a predefined start/end row range (including LAST_ROW_BYTES) to compute region boundaries; one region means no split is needed and the math breaks. Values <= 1 are rejected at construction.

Source

Thrown at hbase/hbase-schema/src/main/java/com/navercorp/pinpoint/hbase/schema/reader/core/CreateTableChange.java:110

            public String toString() {
                return "Manual{" +
                        "splitKeys=" + splitKeys +
                        '}';
            }
        }

        // Implementation copied from hbase's RegionSplitter$UniformSplit
        // https://github.com/apache/hbase/blob/master/hbase-server/src/main/java/org/apache/hadoop/hbase/util/RegionSplitter.java
        class Auto implements SplitOption {
            private static final byte xFF = (byte) 0xFF;
            private static final byte[] FIRST_ROW_BYTES = EMPTY_BYTE_ARRAY;
            private static final byte[] LAST_ROW_BYTES = new byte[]{xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF};

            private final int numRegions;

            public Auto(int numRegions) {
                if (!(numRegions > 1)) {
                    throw new IllegalArgumentException("numRegions must be greater than 1");
                }
                this.numRegions = numRegions;

            }

            @Override
            public byte[][] getSplitKeys() {
                return generateSplitKeys();
            }

            private byte[][] generateSplitKeys() {
                byte[][] splits = Bytes.split(FIRST_ROW_BYTES, LAST_ROW_BYTES, true, numRegions - 1);
                // remove endpoints, which are included in the splits list
                if (splits == null) {
                    throw new IllegalStateException("Could not generate split keys, numRegions : " + numRegions);
                }
                return Arrays.copyOfRange(splits, 1, splits.length - 1);
            }

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Pass numRegions >= 2 to Auto(...)
  2. Use the Manual(splitKeys) option when you need exactly one boundary key or explicit control
  3. For an unsplit table, use the no-split option instead of Auto
  4. Fix the config value feeding numRegions and validate it before constructing

Example fix

// before
SplitOption option = new SplitOption.Auto(1);
// after
SplitOption option = new SplitOption.Auto(8);
Defensive patterns

Strategy: validation

Validate before calling

if (numRegions <= 1) {
    throw new IllegalArgumentException("numRegions must be > 1");
}
new CreateTableChange.SplitOption.Auto(numRegions);

Type guard

boolean isValidRegionCount(int n) {
    return n > 1;
}

Try / catch

try {
    SplitOption opt = new CreateTableChange.SplitOption.Auto(numRegions);
} catch (IllegalArgumentException e) {
    // clamp to a valid default
    opt = new CreateTableChange.SplitOption.Auto(8);
}

Prevention

When it happens

Trigger: Calling new CreateTableChange.SplitOption.Auto(1), Auto(0), or a negative value when defining a CreateTableChange with automatic region splitting.

Common situations: numRegions read from configuration where the default is 0 or 1; a sizing script that returned 1 region for a small table; misunderstanding that Auto(N) creates N regions so N must exceed 1.

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/c9cc4dcfe7e6ea82. Report an issue: GitHub.