alibaba/nacos · error · IllegalArgumentException
illegal hex at index {i}
Error message
illegal hex at index {i} What it means
NacosAiConfigKeyCodec.fromHex encountered a character at position i that is not a valid hexadecimal digit (0-9, a-f, A-F). The encoder only produces lowercase hex, so any non-hex character indicates corruption or external tampering of the encoded segment.
Source
Thrown at api/src/main/java/com/alibaba/nacos/api/ai/model/NacosAiConfigKeyCodec.java:199
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) {
if (candidate == null) {
return null;
}
String prefix = preservedPrefix == null ? "" : preservedPrefix;
if (candidate.length() <= maxLength && !isHashedPhysicalKey(candidate, prefix)) {
return candidate;
}View on GitHub (pinned to 9b989acdf1)
Solutions
- Re-encode the original value with encodeSegment to regenerate clean lowercase hex.
- Sanitize the segment: strip non-hex characters or reject if any are found before decoding.
- Trace the segment through every transport/storage layer to find where the invalid character was introduced.
- Ensure the storage layer preserves exact ASCII bytes (use a binary-safe collation).
Example fix
// before
String bad = "enc.0xGH"; // G, H are not hex
NacosAiConfigKeyCodec.decodeSegment(bad);
// after
if (!bad.substring(4).matches("[0-9a-fA-F]+")) {
bad = NacosAiConfigKeyCodec.encodeSegment(originalValue);
}
NacosAiConfigKeyCodec.decodeSegment(bad); Defensive patterns
Strategy: validation
Validate before calling
public static boolean isCleanHex(String hex) {
if (hex == null || hex.length() % 2 != 0) return false;
for (int i = 0; i < hex.length(); i++) {
if (Character.digit(hex.charAt(i), 16) < 0) return false;
}
return true;
} 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 isCleanHex(hex) && !hex.isEmpty();
} Try / catch
try {
decoded = NacosAiConfigKeyCodec.decodeSegment(segment);
} catch (IllegalArgumentException e) {
logger.error("Corrupted encoded segment with non-hex char: {}", segment);
decoded = NacosAiConfigKeyCodec.encodeSegment(originalValue);
} Prevention
- Use binary-safe storage collations to prevent character mangling.
- Avoid URL-encoding/decoding pass-through on encoded segments.
- Sanitize external input before it reaches the codec.
When it happens
Trigger: An encoded segment contains uppercase letters outside A-F, punctuation, or non-ASCII characters. A URL-decode or character-set conversion mangled the hex string. External system injected unexpected characters into the config key.
Common situations: URL-encoding/decoding applied to a segment that was not designed for URLs. Locale-specific case folding in a database collation. Copy-paste from a rich-text source that inserted invisible characters.
Related errors
- illegal hex length: {len}
- 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/d7953ec5eb95f5db.
Report an issue: GitHub.