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

  1. Inspect e.getMessage() embedded in the thrown text — it carries the specific parseInt failure (e.g. 'For input string: "..."').
  2. Replace the offending node with a plain IntNode containing the decimal value, since real JSON integer literals are the supported path.
  3. 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

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


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/f9fe9ad82a236423.json. Report an issue: GitHub.