apache/kafka · error · ConfigException

Expected value to be a 32-bit integer, but it was a value.ge

Error message

Expected value to be a 32-bit integer, but it was a value.getClass().getName()

What it means

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.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java:742

                case PASSWORD:
                    if (value instanceof Password)
                        return value;
                    else if (value instanceof String)
                        return new Password(trimmed);
                    else
                        throw new ConfigException(name, value, "Expected value to be a string, but it was a " + value.getClass().getName());
                case STRING:
                    if (value instanceof String)
                        return trimmed;
                    else
                        throw new ConfigException(name, value, "Expected value to be a string, but it was a " + value.getClass().getName());
                case INT:
                    if (value instanceof Integer) {
                        return value;
                    } else if (value instanceof String) {
                        return Integer.parseInt(trimmed);
                    } else {
                        throw new ConfigException(name, value, "Expected value to be a 32-bit integer, but it was a " + value.getClass().getName());
                    }
                case SHORT:
                    if (value instanceof Short) {
                        return value;
                    } else if (value instanceof String) {
                        return Short.parseShort(trimmed);
                    } else {
                        throw new ConfigException(name, value, "Expected value to be a 16-bit integer (short), but it was a " + value.getClass().getName());
                    }
                case LONG:
                    if (value instanceof Integer)
                        return ((Integer) value).longValue();
                    if (value instanceof Long)
                        return value;
                    else if (value instanceof String)
                        return Long.parseLong(trimmed);
                    else
                        throw new ConfigException(name, value, "Expected value to be a 64-bit integer (long), but it was a " + value.getClass().getName());

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Coerce the value to int before insertion: ((Number) v).intValue() or Integer.parseInt(v.toString()).
  2. 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.
  3. Ensure custom config sources return Integer or String for INT-declared keys.

Example fix

// before
Map<String,Object> cfg = new HashMap<>();
cfg.put("request.timeout.ms", 30000L); // Long -> ConfigException (INT branch)

// after
Map<String,Object> cfg = new HashMap<>();
cfg.put("request.timeout.ms", 30000);   // int literal -> Integer
cfg.put("request.timeout.ms", "30000"); // or String, parsed by Integer.parseInt
Defensive patterns

Strategy: type-guard

Validate before calling

// An INT config (e.g. "acks" via port-like keys, "request.timeout.ms") got neither Integer nor numeric String.
Object v = props.get(name);
if (v != null) {
    if (v instanceof Integer) { /* ok */ }
    else if (v instanceof String) {
        try { Integer.parseInt(((String) v).trim()); }
        catch (NumberFormatException nfe) {
            throw new IllegalArgumentException("Config '" + name + "' (INT) is not a 32-bit integer: " + v, nfe);
        }
    } else if (v instanceof Number) {
        int i = ((Number) v).intValue();
        props.put(name, i); // coerce Long/Short -> Integer
    } else {
        throw new IllegalArgumentException(
            "Config '" + name + "' (INT) must be Integer or numeric String, got " + v.getClass().getName());
    }
}

Type guard

static boolean isIntConfigValue(Object v) {
    if (v == null) return true;
    if (v instanceof Integer) return true;
    if (v instanceof String) {
        try { Integer.parseInt(((String) v).trim()); return true; }
        catch (NumberFormatException e) { return false; }
    }
    return false; // Long, Double, etc. are NOT accepted by ConfigDef.parseType INT
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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