apache/kafka · error · NumberFormatException
${about}: failed to parse hexadecimal number: ${cause}
Error message
${about}: failed to parse hexadecimal number: ${cause} What it means
Thrown by MessageUtil.jsonNodeToInt after asText() on the node returned a string beginning with '0x' but Integer.parseInt(text.substring(2), 16) failed. Because the textual branch at line 118 already rejects real JSON strings, this path is only reachable for non-int, non-textual nodes (e.g. BigIntegerNode, DoubleNode) whose asText() happens to start with '0x' — an unusual but technically possible input.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/protocol/MessageUtil.java:126
" does not fit in a 32-bit unsigned integer.");
}
return value;
}
public static int jsonNodeToInt(JsonNode node, String about) {
if (node.isInt()) {
return node.asInt();
}
if (node.isTextual()) {
throw new NumberFormatException(about + ": expected an integer or " +
"string type, but got " + node.getNodeType());
}
String text = node.asText();
if (text.startsWith("0x")) {
try {
return Integer.parseInt(text.substring(2), 16);
} catch (NumberFormatException e) {
throw new NumberFormatException(about + ": failed to " +
"parse hexadecimal number: " + e.getMessage());
}
} else {
try {
return Integer.parseInt(text);
} catch (NumberFormatException e) {
throw new NumberFormatException(about + ": failed to " +
"parse number: " + e.getMessage());
}
}
}
public static long jsonNodeToLong(JsonNode node, String about) {
if (node.isLong()) {
return node.asLong();
}
if (node.isTextual()) {
throw new NumberFormatException(about + ": expected an integer or " +View on GitHub (pinned to c31c9215e1)
Solutions
- Inspect e.getMessage() embedded in the thrown text — it carries the specific parseInt failure (e.g. 'For input string: "..."').
- Replace the offending node with a plain IntNode containing the decimal value, since real JSON integer literals are the supported path.
- If you truly need hex input, you must encode it as a JSON integer literal equal to the decimal value; the textual-hex form is rejected upstream by error 441.
Example fix
// before (constructed node, asText() returns "0xZZ") JsonNode n = nodeWhereAsTextStartsWith0xButInvalid; int v = MessageUtil.jsonNodeToInt(n, "field"); // after int v = MessageUtil.jsonNodeToInt(new IntNode(255), "field");
Defensive patterns
Strategy: validation
Validate before calling
String t = node.asText();
if (t != null && t.startsWith("0x")) {
try { Integer.parseUnsignedInt(t.substring(2), 16); }
catch (NumberFormatException ex) { throw new IllegalArgumentException("bad hex: " + t, ex); }
} Type guard
node != null && node.isTextual() && node.asText().matches("0x[0-9A-Fa-f]{1,8}") Try / catch
try { int i = MessageUtil.jsonNodeToInt(node, about); }
catch (NumberFormatException e) { /* malformed hex literal; ask producer to resend clean value */ } Prevention
- Standardize hex literals as 0x-prefixed lowercase with at most 8 hex digits.
- Avoid leading/trailing whitespace and underscores in numeric literals.
- Prefer plain decimal integers over hex unless the field semantics require it.
When it happens
Trigger: A non-integral numeric JSON node whose Jackson asText() representation starts with the literal characters '0x' is passed to a int32 field reader. The hex digits following '0x' are non-parseable as a base-16 integer (empty, contains '8'+'9'+letters beyond F, or overflows Integer range). Realistically only triggered by constructed/edge-case inputs rather than normal operator JSON.
Common situations: Test fixtures that inject BigInteger or custom JsonNode subtypes; programmatic construction of a JsonNode (not parsed from JSON text) where asText() returns a hex form; corrupted/injected protocol fixtures in integration tests.
Related errors
- ${about}: failed to parse number: ${cause}
- ${about}: unable to retrieve Base64-encoded binary data
- ${about}: value ${value} does not fit in a 32-bit unsigned i
- ${about}: expected an integer or string type, but got ${node
- ${about}: expected Base64-encoded binary data.
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/f9fe9ad82a236423.json.
Report an issue: GitHub.