apache/flink · error · IllegalArgumentException

The given value {} is not a power of two.

Error message

The given value {} is not a power of two.

What it means

The second guard in MathUtils.log2strict: after ruling out 0, the bit trick (value & (value - 1)) != 0 detects that value is not an exact power of two, and IllegalArgumentException is thrown naming the value. log2strict exists specifically for sizing math (segments, hash tables) that requires power-of-two dimensions.

Source

Thrown at flink-core/src/main/java/org/apache/flink/util/MathUtils.java:56

        return 31 - Integer.numberOfLeadingZeros(value);
    }

    /**
     * Computes the logarithm of the given value to the base of 2. This method throws an error, if
     * the given argument is not a power of 2.
     *
     * @param value The value to compute the logarithm for.
     * @return The logarithm to the base of 2.
     * @throws ArithmeticException Thrown, if the given value is zero.
     * @throws IllegalArgumentException Thrown, if the given value is not a power of two.
     */
    public static int log2strict(int value) throws ArithmeticException, IllegalArgumentException {
        if (value == 0) {
            throw new ArithmeticException("Logarithm of zero is undefined.");
        }
        if ((value & (value - 1)) != 0) {
            throw new IllegalArgumentException(
                    "The given value " + value + " is not a power of two.");
        }
        return 31 - Integer.numberOfLeadingZeros(value);
    }

    /**
     * Decrements the given number down to the closest power of two. If the argument is a power of
     * two, it remains unchanged.
     *
     * @param value The value to round down.
     * @return The closest value that is a power of two and less or equal than the given value.
     */
    public static int roundDownToPowerOf2(int value) {
        return Integer.highestOneBit(value);
    }

    /**
     * Casts the given value to a 32 bit integer, if it can be safely done. If the cast would change

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Round the input first: use MathUtils.roundDownToPowerOf2(value) (or enforce/round up) before log2strict.
  2. Fix the configuration to a power of two (e.g. 33554432 instead of 32000000 for a 32MB-ish segment).
  3. Add config validation that rejects non-power-of-two values early with a message naming the option key.
  4. If arbitrary sizes must be supported, switch the consumer code from log2strict/indexing to non-power-of-two-safe arithmetic.

Example fix

// before
int segBits = MathUtils.log2strict(segmentSize); // segmentSize = 1000 -> IAE

// after
int segSizePow2 = MathUtils.roundDownToPowerOf2(segmentSize);
int segBits = MathUtils.log2strict(segSizePow2);
Defensive patterns

Strategy: validation

Validate before calling

if (value <= 0 || (value & (value - 1)) != 0) {
    value = MathUtils.roundDownToPowerOf2(value); // or reject
}
int log = MathUtils.log2strict(Math.max(1, value));

Type guard

// Java has no type guard; use a boolean predicate
static boolean isPowerOfTwoSafe(int v) { return v > 0 && (v & (v - 1)) == 0; }

Prevention

When it happens

Trigger: Calling log2strict(v) with v in {3, 5, 6, 7, 9, ...} — any positive value that is not 1, 2, 4, 8, 16, ... Typical sources: user-supplied buffer sizes, segment counts, or parallelism values that bypassed power-of-two validation.

Common situations: Memory segment size or table capacity configured to a round-but-non-power-of-two number like 1000 or 3000000; config parsing that accepts arbitrary ints where the code later requires 2^k; refactors that replaced a rounding step (roundDownToPowerOf2) with a direct pass-through.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/38346d1c18b956a8. Report an issue: GitHub.