{"id":"f9fe9ad82a236423","repo":"apache/kafka","slug":"about-failed-to-parse-hexadecimal-number-ca","errorCode":null,"errorMessage":"${about}: failed to parse hexadecimal number: ${cause}","messagePattern":"(.+?): failed to parse hexadecimal number: (.+?)","errorType":"exception","errorClass":"NumberFormatException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/protocol/MessageUtil.java","lineNumber":126,"sourceCode":"                    \" does not fit in a 32-bit unsigned integer.\");\n        }\n        return value;\n    }\n\n    public static int jsonNodeToInt(JsonNode node, String about) {\n        if (node.isInt()) {\n            return node.asInt();\n        }\n        if (node.isTextual()) {\n            throw new NumberFormatException(about + \": expected an integer or \" +\n                \"string type, but got \" + node.getNodeType());\n        }\n        String text = node.asText();\n        if (text.startsWith(\"0x\")) {\n            try {\n                return Integer.parseInt(text.substring(2), 16);\n            } catch (NumberFormatException e) {\n                throw new NumberFormatException(about + \": failed to \" +\n                    \"parse hexadecimal number: \" + e.getMessage());\n            }\n        } else {\n            try {\n                return Integer.parseInt(text);\n            } catch (NumberFormatException e) {\n                throw new NumberFormatException(about + \": failed to \" +\n                    \"parse number: \" + e.getMessage());\n            }\n        }\n    }\n\n    public static long jsonNodeToLong(JsonNode node, String about) {\n        if (node.isLong()) {\n            return node.asLong();\n        }\n        if (node.isTextual()) {\n            throw new NumberFormatException(about + \": expected an integer or \" +","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/protocol/MessageUtil.java#L108-L144","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before  (constructed node, asText() returns \"0xZZ\")\nJsonNode n = nodeWhereAsTextStartsWith0xButInvalid;\nint v = MessageUtil.jsonNodeToInt(n, \"field\");\n// after\nint v = MessageUtil.jsonNodeToInt(new IntNode(255), \"field\");","handlingStrategy":"validation","validationCode":"String t = node.asText();\nif (t != null && t.startsWith(\"0x\")) {\n    try { Integer.parseUnsignedInt(t.substring(2), 16); }\n    catch (NumberFormatException ex) { throw new IllegalArgumentException(\"bad hex: \" + t, ex); }\n}","typeGuard":"node != null && node.isTextual() && node.asText().matches(\"0x[0-9A-Fa-f]{1,8}\")","tryCatchPattern":"try { int i = MessageUtil.jsonNodeToInt(node, about); }\ncatch (NumberFormatException e) { /* malformed hex literal; ask producer to resend clean value */ }","preventionTips":["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."],"tags":["kafka","protocol","json","serialization","hex","parse-error"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}