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
- Use one of the supported units: Pi/Ti/Gi/Mi/Ki (optionally followed by b/B), e.g. "64Ki" or "64KiB"
- Fall back to decimal units K/M/G/T/P (e.g. "64k") or a plain byte count
- Correct the misspelled/unsupported prefix in the configuration string
- 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
- Restrict size inputs to the five supported binary units Ki/Mi/Gi/Ti/Pi (plus decimal K/M/G/T/P)
- Reject exotic prefixes (Zi/Yi/Ni) at config validation time
- Document the exact supported unit list near the config key
- Add unit tests covering each accepted and rejected unit spelling
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
- Metric [%s] not whitelisted.
- Invalid format of number: number is null
- Invalid format of number: number is blank
- Invalid format of number: %s. Negative value is not allowed.
- Invalid format of number: %s
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/fbf8043801ec438e.
Report an issue: GitHub.