{"id":"ee2c8aa43dcb2f8d","repo":"apache/kafka","slug":"about-expected-an-integer-or-string-type-but","errorCode":null,"errorMessage":"${about}: expected an integer or string type, but got ${nodeType}","messagePattern":"(.+?): expected an integer or string type, but got (.+?)","errorType":"exception","errorClass":"NumberFormatException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/protocol/MessageUtil.java","lineNumber":118,"sourceCode":"        }\n        return value;\n    }\n\n    public static long jsonNodeToUnsignedInt(JsonNode node, String about) {\n        long value = jsonNodeToLong(node, about);\n        if (value < 0 || value > UNSIGNED_INT_MAX) {\n            throw new RuntimeException(about + \": value \" + value +\n                    \" 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        }","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/protocol/MessageUtil.java#L100-L136","documentation":"Thrown by MessageUtil.jsonNodeToInt when the Jackson JsonNode reports isTextual()==true. Note the contradiction with the message text: although it says 'expected an integer or string type', the code as written rejects JSON strings on this branch (line 118), so only JSON integer numbers actually succeed; the string/hex parsing code below is unreachable in practice. This is a long-standing quirk of the generated-message JSON reader.","triggerScenarios":"A JSON object passed to a generated Message.fromJson for a int32 protocol field contains a string value where an integer literal is required. For example {\"acks\": \"1\"} or {\"replication_factor\": \"3\"} (quoted). Jackson parses the quoted token as a TextNode, isInt() is false, isTextual() is true, and line 118 throws NumberFormatException carrying nodeType=STRING.","commonSituations":"Authors hand-writing JSON for kafka-topics --create --replica-assignment, AlterClientQuotas, or rebalance plans quote numeric fields by habit or because a YAML→JSON tool quoted everything; users paste config from documentation that renders numbers as strings; mixing up --if-not-exists numeric flags vs their JSON string variants.","solutions":["Unquote the offending numeric value in the JSON payload (make it a JSON integer literal).","Locate the field via the 'about' prefix in the message — it identifies the message class + field path.","If you need to keep strings in the source format, pre-process with a JSON parser and emit integer tokens before handing the document to the Kafka deserializer.","Do not be misled by the error text mentioning 'string' — strings are not actually accepted here."],"exampleFix":"// before\n{\"replication_factor\": \"3\", \"topic\": \"orders\"}\n// after\n{\"replication_factor\": 3, \"topic\": \"orders\"}","handlingStrategy":"type-guard","validationCode":"if (node == null || !node.isInt()) throw new IllegalArgumentException(\"int field must be a JSON integer\");","typeGuard":"node != null && node.isInt()","tryCatchPattern":"try { int i = MessageUtil.jsonNodeToInt(node, about); }\ncatch (NumberFormatException e) { /* wrong JSON node type for int field; reject record */ }","preventionTips":["Emit Kafka int fields as JSON numbers (IntNode), never as strings, booleans, objects, or arrays.","Pin your JSON schema so numeric fields are typed as integer.","When building JsonNode in Java, use factory.numberNode(int) for integer fields."],"tags":["kafka","protocol","json","serialization","type-mismatch","int32"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}