apache/kafka · error · ConfigException
Expected value to be a 16-bit integer (short), but it was a
Error message
Expected value to be a 16-bit integer (short), but it was a value.getClass().getName()
What it means
Thrown by ConfigDef.parseType in the SHORT branch when the supplied value is neither a java.lang.Short nor a java.lang.String. Type.SHORT accepts a boxed Short (returned as-is) or a String parsed via Short.parseShort(trimmed); any other runtime type is rejected. Kafka declares only a handful of keys as Type.SHORT (for example the replication-related defaults in broker config), and because Java integer literals are int, this fires frequently when callers pass an unqualified int into a SHORT slot.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java:750
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());
case DOUBLE:
if (value instanceof Number)
return ((Number) value).doubleValue();
else if (value instanceof String)
return Double.parseDouble(trimmed);
else
throw new ConfigException(name, value, "Expected value to be a double, but it was a " + value.getClass().getName());
case LIST:View on GitHub (pinned to c31c9215e1)
Solutions
- Box the value as a Short explicitly: (short) value or Short.valueOf(...), or pass it as a String so Short.parseShort handles it.
- When reading config from a typed source, emit the value as a string for SHORT-declared keys.
- Audit which keys are actually Type.SHORT in the relevant ConfigDef (most byte-size configs are INT or LONG) and only coerce those.
Example fix
// before
Map<String,Object> cfg = new HashMap<>();
cfg.put("some.short.key", 1024); // Integer -> ConfigException (SHORT branch)
// after
Map<String,Object> cfg = new HashMap<>();
cfg.put("some.short.key", (short) 1024); // Short
cfg.put("some.short.key", "1024"); // or String, parsed by Short.parseShort Defensive patterns
Strategy: type-guard
Validate before calling
// A SHORT config (e.g. "transaction.timeout.ms", "fetch.min.bytes" where short) got neither Short nor numeric String.
Object v = props.get(name);
if (v != null) {
if (v instanceof Short) { /* ok */ }
else if (v instanceof String) {
try { Short.parseShort(((String) v).trim()); }
catch (NumberFormatException nfe) {
throw new IllegalArgumentException("Config '" + name + "' (SHORT) is not a 16-bit integer: " + v, nfe);
}
} else if (v instanceof Integer) {
int i = (Integer) v;
if (i < Short.MIN_VALUE || i > Short.MAX_VALUE) {
throw new IllegalArgumentException("Config '" + name + "' (SHORT) out of range: " + i);
}
props.put(name, (short) i);
} else if (v instanceof Number) {
props.put(name, ((Number) v).shortValue());
} else {
throw new IllegalArgumentException(
"Config '" + name + "' (SHORT) must be Short or numeric String, got " + v.getClass().getName());
}
} Type guard
static boolean isShortConfigValue(Object v) {
if (v == null) return true;
if (v instanceof Short) return true;
if (v instanceof String) {
try { Short.parseShort(((String) v).trim()); return true; }
catch (NumberFormatException e) { return false; }
}
return false; // Integer/Long are NOT accepted by ConfigDef.parseType SHORT
} Prevention
- ConfigDef accepts only java.lang.Short or a numeric String for SHORT - an Integer value will throw; coerce first.
- Range-check against [-32768, 32767] before assignment; short configs silently overflow if you cast blindly.
- Prefer numeric String values in properties files so Kafka performs the parse with correct range semantics.
- When bridging JSON/YAML numbers (often Long/Integer), explicitly narrow to short after a bounds check.
When it happens
Trigger: Passing an Integer, Long, or non-String/non-Short object for a Type.SHORT config key such as replica.fetch.max.bytes (where applicable), message.max.bytes (INT, not SHORT - check the actual key), or any broker/client key declared with Type.SHORT; building config programmatically with int literals.
Common situations: Programmatic construction where a helper returns int/long and the value is placed in a SHORT slot; Java does not have short literals (an unqualified 1024 is an int), so cfg.put("some.short.key", 1024) boxes to Integer and fails; YAML/JSON sources decoding numbers as Integer or Long.
Related errors
- Expected value to be a 32-bit integer, but it was a value.ge
- Expected value to be either true or false
- Expected value to be a string, but it was a value.getClass()
- Invalid url in bootstrap.servers: {url}
- Invalid url in bootstrap.servers: {url}
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/2aff90fc8fd05a60.json.
Report an issue: GitHub.