apache/hadoop · error · HadoopIllegalArgumentException

Percentage " + percentage + " must be greater than or equal

Error message

Percentage " + percentage + " must be greater than or equal to 0  and less than or equal to 100

What it means

LightWeightGSet.computeCapacity derives a hash-table capacity as a percentage of maxMemory and validates the input: a percentage outside [0.0, 100.0] is rejected with HadoopIllegalArgumentException printing the value and the allowed range. This is the same sizing path Hadoop services use for their GSet-backed maps.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/LightWeightGSet.java:383

   * Let t = percentage of max memory.
   * Let e = round(log_2 t).
   * Then, we choose capacity = 2^e/(size of reference),
   * unless it is outside the close interval [1, 2^30].
   *
   * @param mapName mapName.
   * @param percentage percentage.
   * @return compute capacity.
   */
  public static int computeCapacity(double percentage, String mapName) {
    return computeCapacity(Runtime.getRuntime().maxMemory(), percentage,
        mapName);
  }
  
  @VisibleForTesting
  static int computeCapacity(long maxMemory, double percentage,
      String mapName) {
    if (percentage > 100.0 || percentage < 0.0) {
      throw new HadoopIllegalArgumentException("Percentage " + percentage
          + " must be greater than or equal to 0 "
          + " and less than or equal to 100");
    }
    if (maxMemory < 0) {
      throw new HadoopIllegalArgumentException("Memory " + maxMemory
          + " must be greater than or equal to 0");
    }
    if (percentage == 0.0 || maxMemory == 0) {
      return 0;
    }
    //VM detection
    //See http://java.sun.com/docs/hotspot/HotSpotFAQ.html#64bit_detection
    final String vmBit = System.getProperty("sun.arch.data.model");

    //Percentage of max memory
    final double percentDivisor = 100.0/percentage;
    final double percentMemory = maxMemory/percentDivisor;
    

View on GitHub (pinned to 2add963021)

Solutions

  1. Validate or clamp the percentage to [0, 100] before calling computeCapacity.
  2. When parsing percent strings from config, strip '%' and trim before parseDouble.
  3. Use 0.0 for 'cache disabled' - it is legal and yields capacity 0 - instead of negative sentinel values.

Example fix

// before
double pct = Double.parseDouble(conf.get("cache.memory.percent")); // "25%" -> 25? no: throws later
capacity = LightWeightGSet.computeCapacity(pct, "cache");

// after
double pct = Double.parseDouble(
    conf.get("cache.memory.percent").replace("%", "").trim());
pct = Math.max(0.0, Math.min(100.0, pct));
capacity = LightWeightGSet.computeCapacity(pct, "cache");
Defensive patterns

Strategy: validation

Validate before calling

double pct = Math.max(0.0, Math.min(100.0, rawPercent));
int capacity = LightWeightGSet.computeCapacity(pct, mapName);

Prevention

When it happens

Trigger: Passing a negative or greater-than-100 value - for example a constant typo (0.5 where 50 was meant, since the unit is percent, not a fraction), or Double.parseDouble on a config string like "25%" without stripping the '%' sign.

Common situations: Custom code copying Hadoop's sizing pattern; config keys feeding memory percentages edited to invalid values; unit tests probing boundary values.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/b99d9c07c1b89c75. Report an issue: GitHub.