chinabugotech/hutool · error · UtilException
Illegal hexadecimal character {} at index {}
Error message
Illegal hexadecimal character {} at index {} What it means
Base16Codec.toDigit converts a single hex char to its integer value via Character.digit(ch, 16); when the char is not a valid hex digit (0-9, a-f, A-F) the result is -1 and a UtilException (a RuntimeException) is thrown naming the offending char and its index. This occurs during hex decoding.
Source
Thrown at hutool-core/src/main/java/cn/hutool/core/codec/Base16Codec.java:114
public void appendHex(StringBuilder builder, byte b) {
int high = (b & 0xf0) >>> 4;//高位
int low = b & 0x0f;//低位
builder.append(alphabets[high]);
builder.append(alphabets[low]);
}
/**
* 将十六进制字符转换成一个整数
*
* @param ch 十六进制char
* @param index 十六进制字符在字符数组中的位置
* @return 一个整数
* @throws UtilException 当ch不是一个合法的十六进制字符时,抛出运行时异常
*/
private static int toDigit(char ch, int index) {
int digit = Character.digit(ch, 16);
if (digit < 0) {
throw new UtilException("Illegal hexadecimal character {} at index {}", ch, index);
}
return digit;
}
}
View on GitHub (pinned to 8870454b2a)
Solutions
- Sanitise input: strip 0x prefixes, whitespace, colons and uppercase/lowercase to a-f before decoding.
- Validate with a regex (^[0-9a-fA-F]+$) and even length before calling decode.
- Use HexUtil.decodeHexStr/decodeHex with a try-catch to report the bad input to the user.
Example fix
// before
byte[] b = HexUtil.decodeHex("0x1F:2A");
// after
String clean = input.replaceAll("0x|:|\\s", "");
if (!clean.matches("^[0-9a-fA-F]+$") || clean.length()%2!=0) throw new IllegalArgumentException("bad hex");
byte[] b = HexUtil.decodeHex(clean); Defensive patterns
Strategy: validation
Validate before calling
String clean = input.replaceAll("0x|:|\\s", "");
if (!clean.matches("^[0-9a-fA-F]+$") || clean.length()%2!=0) throw new IllegalArgumentException("invalid hex: " + input); Type guard
static boolean isHex(String s) { return s != null && s.matches("^[0-9a-fA-F]+$") && s.length()%2==0; } Try / catch
try { return HexUtil.decodeHex(s); } catch (UtilException e) { throw new IllegalArgumentException("bad hex input", e); } Prevention
- Strip prefixes/separators and validate hex alphabet before decoding.
- Confirm even length.
When it happens
Trigger: Decoding a string containing non-hex characters (g-z, punctuation, whitespace) via HexUtil.decodeHex or Base16.decode. An odd-length input or characters outside [0-9a-fA-F].
Common situations: Parsing user input or file content assumed to be hex; concatenating hex strings with separators (0x prefix, colons) not stripped; encoding/decoding mismatch (treating base64 as hex).
Related errors
- Invalid char '{}' at [{}]
- invalid number: {number}
- Error Machine number!
- Bad expression '{}':{}, we find ']' but no '[' !
- Bad expression '{}':{}, we find '[' but no ']' !
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/f5413dcf0383f355.
Report an issue: GitHub.