{"record":{"id":"453d2cf12010b387","repo":"apache/cassandra","slug":"unexpected-s-extraneous-bytes-after-s-value","errorCode":null,"errorMessage":"Unexpected %s extraneous bytes after %s value","messagePattern":"Unexpected (.+?) extraneous bytes after (.+?) value","errorType":"validation","errorClass":"MarshalException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/marshal/VectorType.java","lineNumber":381,"sourceCode":"    private void check(List<?> values)\n    {\n        if (values.size() != dimension)\n            throw new MarshalException(String.format(\"Required %d elements, but saw %d\", dimension, values.size()));\n\n        // This code base always works with a list that is RandomAccess, so can use .get to avoid allocation\n        for (int i = 0; i < dimension; i++)\n        {\n            Object value = values.get(i);\n            if (value == null || (value instanceof ByteBuffer && elementSerializer.isNull((ByteBuffer) value)))\n                throw new MarshalException(String.format(\"Element at index %d is null (expected type %s); given %s\", i, elementType.asCQL3Type(), values));\n        }\n    }\n\n    private <V> void checkConsumedFully(V buffer, ValueAccessor<V> accessor, int offset)\n    {\n        int remaining = accessor.sizeFromOffset(buffer, offset);\n        if (remaining > 0)\n            throw new MarshalException(\"Unexpected \" + remaining + \" extraneous bytes after \" + asCQL3Type() + \" value\");\n    }\n    \n    private static void rejectNullOrEmptyValue()\n    {\n        throw new MarshalException(\"Invalid empty vector value\");\n    }\n\n    @Override\n    public ByteBuffer getMaskedValue()\n    {\n        List<ByteBuffer> values = Collections.nCopies(dimension, elementType.getMaskedValue());\n        return serializer.pack(values, ByteBufferAccessor.instance);\n    }\n\n    public abstract class VectorSerializer extends TypeSerializer<List<T>>\n    {\n        public abstract <VL, VR> int compareCustom(VL left, ValueAccessor<VL> accessorL, VR right, ValueAccessor<VR> accessorR);\n","sourceCodeStart":363,"sourceCodeEnd":399,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/marshal/VectorType.java#L363-L399","documentation":"VectorType throws this MarshalException when a serialized vector value contains more bytes than the declared dimension x element-size requires. Cassandra's vector marshaling requires the byte buffer to be fully consumed after reading all elements; leftover trailing bytes mean the value is malformed or was written by a different type definition.","triggerScenarios":"Calling VectorType.fromString / decompose / validate (via decomposeUn Type) on a buffer whose byte count exceeds dimension * elementLength, e.g. passing a value with extra trailing bytes, or validating a buffer typed as a vector with a smaller dimension than the data was written for.","commonSituations":"Schema changed a vector column's dimension or element type after data was written; manually constructed ByteBuffers for tests; corrupted SSTable or commit-log data; mixing up fixed-length element types (e.g. float vs double).","solutions":["Check the buffer length equals the exact expected size (dimension * element type size) before passing it to the vector type's validate/decompose methods","Verify the vector column's dimension and element type in the schema match how the value was produced","Re-write the affected data with the correct type; if data on disk is corrupted, run scrub or restore from backup","If from user input, trim or reject values with trailing bytes at parse time"],"exampleFix":"// before\nByteBuffer value = ByteBuffer.allocate(20); // 5 floats written, but column is vector<float, 4>\nVectorType.getInstance(FloatType.instance, 4).validate(value);\n// after\nif (value.remaining() != 4 * 4) throw new IllegalArgumentException(\"expected 16 bytes for vector<float,4>\");\nVectorType.getInstance(FloatType.instance, 4).validate(value);","handlingStrategy":"validation","validationCode":"int expected = dimension * elementType.valueLengthIfFixed();\nif (value == null || value.remaining() != expected) throw new IllegalArgumentException(\"expected \" + expected + \" bytes\");","typeGuard":null,"tryCatchPattern":"try { vectorType.validate(buffer); } catch (MarshalException e) { log.error(\"malformed vector value: {}\", e.getMessage()); throw new IllegalArgumentException(e); }","preventionTips":["Compute exact serialized size from dimension and element type before passing buffers","Don't hand-construct vector byte buffers; use the type's serializer","Re-check schema dimension after any ALTER TABLE on vector columns"],"tags":["cassandra","serialization","marshal-exception","vector-type"],"backgroundTag":"invalid-argument-format","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}