apache/kafka · error · SchemaException

Bytes size ${size} cannot be negative

Error message

Bytes size ${size} cannot be negative

What it means

Thrown by BYTES.read() when the INT32 size prefix decoded to a negative value. The BYTES type encodes length as a signed INT32 and does not support a null sentinel, so a negative size indicates either a NULLABLE_BYTES field (size -1 means null) was misread as BYTES, or the buffer is corrupt/misaligned. Raised as a SchemaException before any bytes are sliced.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/protocol/types/Type.java:697

                    "A null string is represented with a length of 0.";
        }
    };

    public static final DocumentedType BYTES = new DocumentedType() {
        @Override
        public void write(ByteBuffer buffer, Object o) {
            ByteBuffer arg = (ByteBuffer) o;
            int pos = arg.position();
            buffer.putInt(arg.remaining());
            buffer.put(arg);
            arg.position(pos);
        }

        @Override
        public Object read(ByteBuffer buffer) {
            int size = buffer.getInt();
            if (size < 0)
                throw new SchemaException("Bytes size " + size + " cannot be negative");

            return bytesRead(buffer, size);
        }

        @Override
        public int sizeOf(Object o) {
            ByteBuffer buffer = (ByteBuffer) o;
            return 4 + buffer.remaining();
        }

        @Override
        public String typeName() {
            return "BYTES";
        }

        @Override
        public ByteBuffer validate(Object item) {
            if (item instanceof ByteBuffer)

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Switch the reader to NULLABLE_BYTES if the field can legitimately be null at the negotiated API version.
  2. Re-decode preceding fields to confirm the buffer position is correct at the failing field.
  3. Match client and broker versions for the API key to ensure the size prefix encoding agrees.
  4. Inspect the raw bytes at the failure offset for corruption.

Example fix

// before: decoding a possibly-null byte field as BYTES
Object v = Type.BYTES.read(buffer); // throws on size == -1

// after: use the nullable variant
Object v = Type.NULLABLE_BYTES.read(buffer); // size -1 -> null
Defensive patterns

Strategy: try-catch

Validate before calling

// BYTES.read() reads the INT32 size internally; a negative size is corrupt
// and there is no public pre-validation hook without duplicating getInt().
try {
    java.nio.ByteBuffer value = (java.nio.ByteBuffer) org.apache.kafka.common.protocol.types.Type.BYTES.read(buffer);
} catch (org.apache.kafka.common.protocol.types.SchemaException e) {
    // recover
}

Try / catch

try {
    java.nio.ByteBuffer value = (java.nio.ByteBuffer) org.apache.kafka.common.protocol.types.Type.BYTES.read(buffer);
} catch (org.apache.kafka.common.protocol.types.SchemaException e) {
    if (e.getMessage().contains("cannot be negative")) {
        throw new IllegalArgumentException("Malformed BYTES field: negative size", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: BYTES.read(buffer) where buffer.getInt() < 0. Reached when a field encoded as NULLABLE_BYTES is decoded with the non-nullable BYTES type, or when an earlier field's mis-decoded length shifted the position so the size prefix lands on non-length bytes.

Common situations: Schema/nullable mismatch between writer and reader (e.g. API version bump that introduced nullability on a byte-array field). Buffer position corruption from an earlier wrong-length field. Custom interceptors rewriting the payload.

Related errors


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