apache/kafka · error · RuntimeException

${about}: value ${value} does not fit in a 16-bit unsigned i

Error message

${about}: value ${value} does not fit in a 16-bit unsigned integer.

What it means

Thrown by MessageUtil.jsonNodeToUnsignedShort as a RuntimeException when the parsed integer is < 0 or > UNSIGNED_SHORT_MAX (65535). It guards JSON-driven deserialization of a protocol field typed as an unsigned 16-bit integer; values outside [0, 65535] cannot be stored losslessly in a Java int-as-unsigned-short and are rejected. Used by message fields that pack a 16-bit unsigned quantity (e.g. some api-key/size-like fields).

Source

Thrown at clients/src/main/java/org/apache/kafka/common/protocol/MessageUtil.java:98

            throw new RuntimeException(about + ": value " + value +
                " does not fit in an 8-bit signed integer.");
        }
        return (byte) value;
    }

    public static short jsonNodeToShort(JsonNode node, String about) {
        int value = jsonNodeToInt(node, about);
        if ((value < Short.MIN_VALUE) || (value > Short.MAX_VALUE)) {
            throw new RuntimeException(about + ": value " + value +
                " does not fit in a 16-bit signed integer.");
        }
        return (short) value;
    }

    public static int jsonNodeToUnsignedShort(JsonNode node, String about) {
        int value = jsonNodeToInt(node, about);
        if (value < 0 || value > UNSIGNED_SHORT_MAX) {
            throw new RuntimeException(about + ": value " + value +
                " does not fit in a 16-bit unsigned integer.");
        }
        return value;
    }

    public static long jsonNodeToUnsignedInt(JsonNode node, String about) {
        long value = jsonNodeToLong(node, about);
        if (value < 0 || value > UNSIGNED_INT_MAX) {
            throw new RuntimeException(about + ": value " + value +
                    " does not fit in a 32-bit unsigned integer.");
        }
        return value;
    }

    public static int jsonNodeToInt(JsonNode node, String about) {
        if (node.isInt()) {
            return node.asInt();
        }

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Find the field named in 'about' and bring its value into [0, 65535].
  2. If the value is legitimately larger, change the field's target type (e.g. to int) in the message definition and regenerate the protocol classes.
  3. For negative inputs, check whether the upstream producer of the JSON mishandled a signed/unsigned conversion.

Example fix

// before
{ "clientId": 70000 }

// after
{ "clientId": 12 }
Defensive patterns

Strategy: validation

Validate before calling

// MessageUtil.jsonNodeToUnsignedShort requires [0, 65535].
int value = node.asInt();
if (value < 0 || value > MessageUtil.UNSIGNED_SHORT_MAX) {
    throw new IllegalArgumentException(about + ": value " + value + " outside uint16 range [0,65535]");
}
int u16 = MessageUtil.jsonNodeToUnsignedShort(node, about);

Type guard

static boolean isValidUnsignedShort(int v) {
    return v >= 0 && v <= MessageUtil.UNSIGNED_SHORT_MAX; // 65535
}

Try / catch

try {
    int u16 = MessageUtil.jsonNodeToUnsignedShort(node, about);
} catch (RuntimeException e) {
    log.error("{}: uint16 field out of range", about, e);
    rejectMessage(about, e);
}

Prevention

When it happens

Trigger: A JSON field mapped to an unsigned-short protocol message field receives a negative integer or a value > 65535; jsonNodeToInt parses it and the bounds check throws.

Common situations: Passing a signed-negative or overly large port/size/id via JSON tooling; assuming the field is a 32-bit int when the protocol declares it uint16; typo producing a five/six-digit value beyond 65535.

Related errors


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