apache/cassandra · error · InvalidTypeException

Invalid 16-bits integer value, expecting 2 bytes but got %d

Error message

Invalid 16-bits integer value, expecting 2 bytes but got %d

What it means

Thrown by ShortCodec.deserializeNoBoxing when the ByteBuffer does not contain exactly 2 bytes, the wire size of a CQL smallint. Null/empty buffers return 0; any other length cannot be read as a 16-bit signed integer.

Source

Thrown at src/java/org/apache/cassandra/cql3/functions/types/TypeCodec.java:1645

        {
            if (value == null) return "NULL";
            return Short.toString(value);
        }

        @Override
        public ByteBuffer serializeNoBoxing(short value, ProtocolVersion protocolVersion)
        {
            ByteBuffer bb = ByteBuffer.allocate(2);
            bb.putShort(0, value);
            return bb;
        }

        @Override
        public short deserializeNoBoxing(ByteBuffer bytes, ProtocolVersion protocolVersion)
        {
            if (bytes == null || bytes.remaining() == 0) return 0;
            if (bytes.remaining() != 2)
                throw new InvalidTypeException(
                "Invalid 16-bits integer value, expecting 2 bytes but got " + bytes.remaining());

            return bytes.getShort(bytes.position());
        }
    }

    /**
     * This codec maps a CQL {@link DataType#cint()} to a Java {@link Integer}.
     */
    private static class IntCodec extends PrimitiveIntCodec
    {

        private static final IntCodec instance = new IntCodec();

        private IntCodec()
        {
            super(DataType.cint());
        }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Confirm the column's CQL type (smallint = 2 bytes) and select the matching codec.
  2. Log bytes.remaining() on failure to identify the true encoded width and reroute to ByteCodec/IntCodec/LongCodec as appropriate.
  3. Prefer typed row getters (getShort/getInt) over manual codec invocation so the codec matches the declared type.
  4. Align schema between producer and consumer clusters, or add a migration for the column.

Example fix

// before
short s = new ShortCodec().deserializeNoBoxing(bytes, ProtocolVersion.V4);
// after
int n = bytes.remaining();
if (n == 2)
    short s = new ShortCodec().deserializeNoBoxing(bytes, ProtocolVersion.V4);
else if (n == 4)
    int i = new IntCodec().deserializeNoBoxing(bytes, ProtocolVersion.V4);
else
    throw new IllegalArgumentException("Unexpected smallint width: " + n);
Defensive patterns

Strategy: validation

Validate before calling

if (bytes == null || bytes.remaining() == 0) return (short) 0;
if (bytes.remaining() != 2)
    throw new IllegalArgumentException("Expected 2 bytes for smallint, got " + bytes.remaining());

Type guard

boolean isShortSized(ByteBuffer b) { return b != null && (b.remaining() == 0 || b.remaining() == 2); }

Try / catch

try { return codec.deserializeNoBoxing(bytes, protocolVersion); }
catch (InvalidTypeException e) {
    log.warn("Smallint deserialization failed: {} bytes", bytes.remaining());
    return (short) 0;
}

Prevention

When it happens

Trigger: Calling ShortCodec.deserializeNoBoxing(bytes, protocolVersion) with a ByteBuffer whose remaining() is 1, 4, or 8, typically when a tinyint/int/bigint payload is deserialized as smallint.

Common situations: Environment schema drift (column types altered in one cluster only), manual parsing of UDT or collection elements with the wrong codec, or replaying binary logs/legacy data with mixed widths.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/0ec8257d476f0bf0. Report an issue: GitHub.