alibaba/nacos · error · IllegalArgumentException
illegal hex length: {len}
Error message
illegal hex length: {len} What it means
NacosAiConfigKeyCodec.fromHex received a hex string whose length is odd. Every byte requires two hex characters, so an odd-length hex payload is structurally invalid and cannot be decoded into bytes.
Source
Thrown at api/src/main/java/com/alibaba/nacos/api/ai/model/NacosAiConfigKeyCodec.java:192
if (hex.isEmpty()) {
throw new IllegalArgumentException("empty payload after " + ENCODED_PREFIX);
}
return new String(fromHex(hex), StandardCharsets.UTF_8);
}
private static String toHex(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
for (byte b : bytes) {
sb.append(Character.forDigit((b >> 4) & 0xF, 16));
sb.append(Character.forDigit(b & 0xF, 16));
}
return sb.toString();
}
private static byte[] fromHex(String hex) {
int len = hex.length();
if ((len & 1) != 0) {
throw new IllegalArgumentException("illegal hex length: " + len);
}
byte[] out = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
int hi = Character.digit(hex.charAt(i), 16);
int lo = Character.digit(hex.charAt(i + 1), 16);
if (hi < 0 || lo < 0) {
throw new IllegalArgumentException("illegal hex at index " + i);
}
out[i / 2] = (byte) ((hi << 4) + lo);
}
return out;
}
private static boolean hasReservedEncodedPrefix(String value) {
return value.regionMatches(true, 0, ENCODED_PREFIX, 0, ENCODED_PREFIX.length());
}
private static String fitToLength(String candidate, int maxLength, String preservedPrefix) {View on GitHub (pinned to 9b989acdf1)
Solutions
- Re-encode the original logical value with encodeSegment to produce a correct even-length hex string.
- Inspect the stored segment byte-by-byte to find where truncation occurred.
- Add a pre-check: if (hex.length() % 2 != 0) reject or re-encode before calling decodeSegment.
- Check the database schema column length against the maximum encoded segment size.
Example fix
// before String bad = "enc.0a1"; // odd length NacosAiConfigKeyCodec.decodeSegment(bad); // after -- re-encode from source of truth String good = NacosAiConfigKeyCodec.encodeSegment(originalValue); NacosAiConfigKeyCodec.decodeSegment(good);
Defensive patterns
Strategy: validation
Validate before calling
public static boolean isValidHex(String hex) {
return hex != null && hex.length() % 2 == 0 && hex.matches("[0-9a-fA-F]+");
} Type guard
public static boolean isDecodableSegment(String s) {
if (s == null || s.isEmpty()) return true;
if (!s.startsWith(NacosAiConfigKeyCodec.ENCODED_PREFIX)) return true;
String hex = s.substring(NacosAiConfigKeyCodec.ENCODED_PREFIX.length());
return !hex.isEmpty() && hex.length() % 2 == 0 && hex.matches("[0-9a-fA-F]+");
} Try / catch
try {
String decoded = NacosAiConfigKeyCodec.decodeSegment(segment);
} catch (IllegalArgumentException e) {
// segment is corrupted; re-encode from canonical source or skip
decoded = reEncodeFromSource(segment);
} Prevention
- Re-encode from the original logical value rather than repairing hex by hand.
- Ensure storage columns have sufficient length for encoded segments.
- Validate encoded segments after any data migration.
When it happens
Trigger: An encoded segment ('enc.' + hex) was truncated by one character. A custom or external process generated a partial hex string. Character encoding mismatch or copy-paste dropped a trailing nibble.
Common situations: Database column truncation (e.g. VARCHAR length off by one). Manual editing of a stored config key. A bug in a serialization layer that strips whitespace or control characters from hex output.
Related errors
- illegal hex at index {i}
- empty payload after enc.
- Agent Version storage descriptor must be a JSON object
- Physical key prefix leaves insufficient room for a SHA-256 d
- 20002
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/02f6a7648449de3b.
Report an issue: GitHub.