apache/druid · error · IllegalArgumentException

Invalid format of number [%s]. The unit should be one of Pi/

Error message

Invalid format of number [%s]. The unit should be one of Pi/Ti/Gi/Mi/Ki

What it means

HumanReadableBytes.parseInner throws this IllegalArgumentException when the string ends in 'i' but the remaining prefix is too short or not one of the supported binary units (Ki/Mi/Gi/Ti/Pi). Only those five binary prefixes are accepted before the 'i'.

Source

Thrown at processing/src/main/java/org/apache/druid/java/util/common/HumanReadableBytes.java:167

    int lastDigitIndex = number.length() - 1;
    boolean isBinaryByte = false;
    char unit = number.charAt(lastDigitIndex--);
    if (unit == 'b') {
      //unit ends with 'b' must be format of KiB/MiB/GiB/TiB/PiB, so at least 3 extra characters are required
      if (lastDigitIndex < 2) {
        throw new IAE("Invalid format of number: %s", rawNumber);
      }
      if (number.charAt(lastDigitIndex--) != 'i') {
        throw new IAE("Invalid format of number: %s", rawNumber);
      }

      unit = number.charAt(lastDigitIndex--);
      isBinaryByte = true;
    } else if (unit == 'i') {
      //unit ends with 'i' must be format of Ki/Mi/Gi/Ti/Pi, so at least 2 extra characters are required
      if (lastDigitIndex < 1) {
        throw new IAE("Invalid format of number [%s]. The unit should be one of Pi/Ti/Gi/Mi/Ki", rawNumber);
      }
      unit = number.charAt(lastDigitIndex--);
      isBinaryByte = true;
    }

    long base = 1;
    switch (unit) {
      case 'k':
        base = isBinaryByte ? 1024 : 1_000;
        break;

      case 'm':
        base = isBinaryByte ? 1024 * 1024 : 1_000_000;
        break;

      case 'g':
        base = isBinaryByte ? 1024 * 1024 * 1024 : 1_000_000_000;
        break;

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Use one of the supported units: Pi/Ti/Gi/Mi/Ki (optionally followed by b/B), e.g. "64Ki" or "64KiB"
  2. Fall back to decimal units K/M/G/T/P (e.g. "64k") or a plain byte count
  3. Correct the misspelled/unsupported prefix in the configuration string
  4. Catch IAE and validate config at startup with a message listing acceptable units

Example fix

// before
long bytes = HumanReadableBytes.parse("64zi"); // 'z' is not a supported unit
// after
long bytes = HumanReadableBytes.parse("64GiB");
Defensive patterns

Strategy: validation

Validate before calling

private static final Set<Character> VALID_PREFIX = Set.of('k','m','g','t','p');
String s = raw == null ? "" : raw.trim().toLowerCase();
int i = s.indexOf('i');
if (i > 0) {
  char prefix = s.charAt(i - 1);
  boolean prefixIsDigitOrValid = Character.isDigit(prefix) || VALID_PREFIX.contains(prefix);
  if (!prefixIsDigitOrValid) throw new IllegalArgumentException("Unsupported unit prefix in: " + raw);
}

Try / catch

try {
  long bytes = HumanReadableBytes.parse(raw);
} catch (IAE e) {
  throw new IllegalArgumentException("Unit must be one of Pi/Ti/Gi/Mi/Ki (optionally + b/B): " + raw, e);
}

Prevention

When it happens

Trigger: Calling parse with values like "xi", "5kiB" typed as "5kib" with an invalid prefix letter, or strings like "100bi" where the character before 'i' is not one of k/m/g/t/p.

Common situations: Misspelled units such as "Zi"/"Yi" (not supported), "NiB", or locale-mangled characters; users assuming all SI prefixes (e.g. 'h', 'da') work; hand-edited configs with stray characters.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/fbf8043801ec438e. Report an issue: GitHub.