{"id":"6227d871928187f3","repo":"apache/kafka","slug":"bytes-size-size-cannot-be-negative","errorCode":null,"errorMessage":"Bytes size ${size} cannot be negative","messagePattern":"Bytes size (.+?) cannot be negative","errorType":"exception","errorClass":"SchemaException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/protocol/types/Type.java","lineNumber":697,"sourceCode":"                    \"A null string is represented with a length of 0.\";\n        }\n    };\n\n    public static final DocumentedType BYTES = new DocumentedType() {\n        @Override\n        public void write(ByteBuffer buffer, Object o) {\n            ByteBuffer arg = (ByteBuffer) o;\n            int pos = arg.position();\n            buffer.putInt(arg.remaining());\n            buffer.put(arg);\n            arg.position(pos);\n        }\n\n        @Override\n        public Object read(ByteBuffer buffer) {\n            int size = buffer.getInt();\n            if (size < 0)\n                throw new SchemaException(\"Bytes size \" + size + \" cannot be negative\");\n\n            return bytesRead(buffer, size);\n        }\n\n        @Override\n        public int sizeOf(Object o) {\n            ByteBuffer buffer = (ByteBuffer) o;\n            return 4 + buffer.remaining();\n        }\n\n        @Override\n        public String typeName() {\n            return \"BYTES\";\n        }\n\n        @Override\n        public ByteBuffer validate(Object item) {\n            if (item instanceof ByteBuffer)","sourceCodeStart":679,"sourceCodeEnd":715,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/protocol/types/Type.java#L679-L715","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Switch the reader to NULLABLE_BYTES if the field can legitimately be null at the negotiated API version.","Re-decode preceding fields to confirm the buffer position is correct at the failing field.","Match client and broker versions for the API key to ensure the size prefix encoding agrees.","Inspect the raw bytes at the failure offset for corruption."],"exampleFix":"// before: decoding a possibly-null byte field as BYTES\nObject v = Type.BYTES.read(buffer); // throws on size == -1\n\n// after: use the nullable variant\nObject v = Type.NULLABLE_BYTES.read(buffer); // size -1 -> null","handlingStrategy":"try-catch","validationCode":"// BYTES.read() reads the INT32 size internally; a negative size is corrupt\n// and there is no public pre-validation hook without duplicating getInt().\ntry {\n    java.nio.ByteBuffer value = (java.nio.ByteBuffer) org.apache.kafka.common.protocol.types.Type.BYTES.read(buffer);\n} catch (org.apache.kafka.common.protocol.types.SchemaException e) {\n    // recover\n}","typeGuard":null,"tryCatchPattern":"try {\n    java.nio.ByteBuffer value = (java.nio.ByteBuffer) org.apache.kafka.common.protocol.types.Type.BYTES.read(buffer);\n} catch (org.apache.kafka.common.protocol.types.SchemaException e) {\n    if (e.getMessage().contains(\"cannot be negative\")) {\n        throw new IllegalArgumentException(\"Malformed BYTES field: negative size\", e);\n    }\n    throw e;\n}","preventionTips":["For fields that may legitimately be null, use NULLABLE_BYTES (sentinel size -1) instead of BYTES — only NULLABLE_BYTES treats -1 as null.","A negative INT32 size on BYTES.read is wire corruption; close/discard the frame rather than retrying.","Pair this catch with a buffer-position reset (or mark/reset) so downstream parsing isn't left mid-field."],"tags":["protocol","serialization","schema","bytes","nullability"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}