{"id":"4f58430615137b1a","repo":"apache/kafka","slug":"expected-value-to-be-a-32-bit-integer-but-it-was","errorCode":null,"errorMessage":"Expected value to be a 32-bit integer, but it was a value.getClass().getName()","messagePattern":"Expected value to be a 32-bit integer, but it was a value\\.getClass\\(\\)\\.getName\\(\\)","errorType":"validation","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java","lineNumber":742,"sourceCode":"                case PASSWORD:\n                    if (value instanceof Password)\n                        return value;\n                    else if (value instanceof String)\n                        return new Password(trimmed);\n                    else\n                        throw new ConfigException(name, value, \"Expected value to be a string, but it was a \" + value.getClass().getName());\n                case STRING:\n                    if (value instanceof String)\n                        return trimmed;\n                    else\n                        throw new ConfigException(name, value, \"Expected value to be a string, but it was a \" + value.getClass().getName());\n                case INT:\n                    if (value instanceof Integer) {\n                        return value;\n                    } else if (value instanceof String) {\n                        return Integer.parseInt(trimmed);\n                    } else {\n                        throw new ConfigException(name, value, \"Expected value to be a 32-bit integer, but it was a \" + value.getClass().getName());\n                    }\n                case SHORT:\n                    if (value instanceof Short) {\n                        return value;\n                    } else if (value instanceof String) {\n                        return Short.parseShort(trimmed);\n                    } else {\n                        throw new ConfigException(name, value, \"Expected value to be a 16-bit integer (short), but it was a \" + value.getClass().getName());\n                    }\n                case LONG:\n                    if (value instanceof Integer)\n                        return ((Integer) value).longValue();\n                    if (value instanceof Long)\n                        return value;\n                    else if (value instanceof String)\n                        return Long.parseLong(trimmed);\n                    else\n                        throw new ConfigException(name, value, \"Expected value to be a 64-bit integer (long), but it was a \" + value.getClass().getName());","sourceCodeStart":724,"sourceCodeEnd":760,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java#L724-L760","documentation":"Thrown by ConfigDef.parseType in the INT branch when the supplied value is neither a java.lang.Integer nor a java.lang.String. Type.INT accepts an already-boxed Integer (returned as-is) or a String that it parses via Integer.parseInt(trimmed); any other runtime type (Long, Double, BigInteger, Boolean) is rejected. Note this fires before parseInt, so a malformed numeric string surfaces as NumberFormatException, not this message.","triggerScenarios":"Passing a Long, Double, Float, BigDecimal, or any non-Integer/non-String object for a Type.INT config such as request.timeout.ms, session.timeout.ms, max.poll.records, retries, or batch.size; building the config map from a typed source that upcasts small numbers to Long.","commonSituations":"Config loaded from JSON/YAML where all numbers are decoded as Long (Jackson with USE_LONG_FOR_INTS); SDK helper that returns a long for a duration/size and the value is merged into the Kafka map unconverted; database-driven config table storing the column as BIGINT.","solutions":["Coerce the value to int before insertion: ((Number) v).intValue() or Integer.parseInt(v.toString()).","When loading from JSON/YAML, disable eager long upcast (e.g. Jackson DeserializationFeature.USE_BIG_INTEGER_FOR_INTS off, or read with asInt()) so integer-shaped values stay Integer.","Ensure custom config sources return Integer or String for INT-declared keys."],"exampleFix":"// before\nMap<String,Object> cfg = new HashMap<>();\ncfg.put(\"request.timeout.ms\", 30000L); // Long -> ConfigException (INT branch)\n\n// after\nMap<String,Object> cfg = new HashMap<>();\ncfg.put(\"request.timeout.ms\", 30000);   // int literal -> Integer\ncfg.put(\"request.timeout.ms\", \"30000\"); // or String, parsed by Integer.parseInt","handlingStrategy":"type-guard","validationCode":"// An INT config (e.g. \"acks\" via port-like keys, \"request.timeout.ms\") got neither Integer nor numeric String.\nObject v = props.get(name);\nif (v != null) {\n    if (v instanceof Integer) { /* ok */ }\n    else if (v instanceof String) {\n        try { Integer.parseInt(((String) v).trim()); }\n        catch (NumberFormatException nfe) {\n            throw new IllegalArgumentException(\"Config '\" + name + \"' (INT) is not a 32-bit integer: \" + v, nfe);\n        }\n    } else if (v instanceof Number) {\n        int i = ((Number) v).intValue();\n        props.put(name, i); // coerce Long/Short -> Integer\n    } else {\n        throw new IllegalArgumentException(\n            \"Config '\" + name + \"' (INT) must be Integer or numeric String, got \" + v.getClass().getName());\n    }\n}","typeGuard":"static boolean isIntConfigValue(Object v) {\n    if (v == null) return true;\n    if (v instanceof Integer) return true;\n    if (v instanceof String) {\n        try { Integer.parseInt(((String) v).trim()); return true; }\n        catch (NumberFormatException e) { return false; }\n    }\n    return false; // Long, Double, etc. are NOT accepted by ConfigDef.parseType INT\n}","tryCatchPattern":null,"preventionTips":["Note ConfigDef only accepts java.lang.Integer or a numeric String for INT - a bare Long/Short will throw; coerce to Integer first.","When reading from JSON (where numbers may parse as Long), explicitly cast/Range-check to int before putting into props.","Validate numeric bounds (e.g. timeout > 0, port 1..65535) in the same loader that coerces the type.","Keep numeric configs as String in properties files and let Kafka parse them, avoiding Java autoboxing surprises."],"tags":["config","integer","type-coercion","programmatic"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}