chinabugotech/hutool · error · UtilException
BAD_INPUT
Error message
BAD_INPUT
What it means
Thrown by PunyCode.decode() when the input string ends prematurely mid-variable-length-integer, i.e., when the inner decoding loop reaches the end of the input (d == length) before completing the current digit sequence. This indicates a malformed or truncated Punycode string that cannot be fully parsed.
Source
Thrown at hutool-core/src/main/java/cn/hutool/core/codec/PunyCode.java:204
int d = input.lastIndexOf(DELIMITER);
if (d > 0) {
for (int j = 0; j < d; j++) {
final char c = input.charAt(j);
if (isBasic(c)) {
output.append(c);
}
}
d++;
} else {
d = 0;
}
final int length = input.length();
while (d < length) {
int oldi = i;
int w = 1;
for (int k = BASE; ; k += BASE) {
if (d == length) {
throw new UtilException("BAD_INPUT");
}
int c = input.charAt(d++);
int digit = codepoint2digit(c);
if (digit > (Integer.MAX_VALUE - i) / w) {
throw new UtilException("OVERFLOW");
}
i = i + digit * w;
int t;
if (k <= bias) {
t = TMIN;
} else if (k >= bias + TMAX) {
t = TMAX;
} else {
t = k - bias;
}
if (digit < t) {
break;
}View on GitHub (pinned to 8870454b2a)
Solutions
- Validate the Punycode string is well-formed before decoding — check it only contains [a-z0-9-] characters.
- Catch UtilException around decode() and report the input as malformed.
- Use decodeDomain() for full domain processing which handles the xn-- prefix correctly per label.
Example fix
// before
String decoded = PunyCode.decode("xn--fiq"); // truncated — throws BAD_INPUT
// after
try {
String decoded = PunyCode.decode(input);
} catch (UtilException e) {
if ("BAD_INPUT".equals(e.getMessage())) {
return input; // fall back to raw string
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate Punycode charset before decoding
boolean valid = input != null && input.matches("^[a-z0-9-]*$"); Try / catch
try {
String decoded = PunyCode.decode(input);
} catch (UtilException e) {
if ("BAD_INPUT".equals(e.getMessage())) {
return input; // fall back to raw string if not valid Punycode
}
throw e;
} Prevention
- Validate Punycode input character set before decoding.
- Use decodeDomain() for full domain processing.
- Handle BAD_INPUT gracefully by falling back to the raw string.
When it happens
Trigger: Calling PunyCode.decode(input) with a string that is truncated or malformed — the decoder expects a complete sequence of base-36 digit characters but encounters the end of the string mid-sequence. This happens with corrupted, manually truncated, or incorrectly generated Punycode strings.
Common situations: Truncated domain names from user input or URL parsing. Corrupted data in transit or storage. Manually constructed or partially overwritten Punycode strings. Inconsistent prefix handling (passing 'xn--' prefix to decode() which strips it, leaving a malformed remainder).
Related errors
- OVERFLOW
- invalid hash: {hash}
- Invalid alphabet for hash
- Incorrect morse.
- Illegal hexadecimal character {} at index {}
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/ff39e31f3d117b97.
Report an issue: GitHub.