{"record":{"id":"b83474886cf05b13","repo":"apache/cassandra","slug":"the-data-cannot-be-deserialized-as-a-set","errorCode":null,"errorMessage":"The data cannot be deserialized as a set","messagePattern":"The data cannot be deserialized as a set","errorType":"validation","errorClass":"MarshalException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/serializers/SetSerializer.java","lineNumber":103,"sourceCode":"            if (!accessor.isEmptyFromOffset(input, offset))\n                throw new MarshalException(\"Unexpected extraneous bytes after set value\");\n        }\n        catch (BufferUnderflowException | IndexOutOfBoundsException e)\n        {\n            throw new MarshalException(\"Not enough bytes to read a set\");\n        }\n    }\n\n    @Override\n    public <V> Set<T> deserialize(V input, ValueAccessor<V> accessor)\n    {\n        try\n        {\n            int n = readCollectionSize(input, accessor);\n            int offset = sizeOfCollectionSize();\n\n            if (n < 0)\n                throw new MarshalException(\"The data cannot be deserialized as a set\");\n\n            // If the received bytes are not corresponding to a set, n might be a huge number.\n            // In such a case we do not want to initialize the set with that initialCapacity as it can result\n            // in an OOM when add is called (see CASSANDRA-12618). On the other hand we do not want to have to resize\n            // the set if we can avoid it, so we put a reasonable limit on the initialCapacity.\n            Set<T> l = new LinkedHashSet<>(Math.min(n, 256));\n\n            for (int i = 0; i < n; i++)\n            {\n                V value = readNonNullValue(input, accessor, offset);\n                offset += sizeOfValue(value, accessor);\n                elements.validate(value, accessor);\n                l.add(elements.deserialize(value, accessor));\n            }\n            if (!accessor.isEmptyFromOffset(input, offset))\n                throw new MarshalException(\"Unexpected extraneous bytes after set value\" + l + \",\" + accessor.toHex(input));\n            return l;\n        }","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/serializers/SetSerializer.java#L85-L121","documentation":"SetSerializer.deserialize reads a 4-byte signed element count; a negative count cannot represent a valid set, so deserialization is aborted. This typically indicates bit-level corruption of the count field or reading bytes with the wrong layout/type. The guard prevents allocating a nonsensical collection.","triggerScenarios":"Deserializing a buffer whose first 4 bytes, interpreted as an int, are negative — e.g. corrupt storage bytes, wrong column type, or reading a non-set value as a set.","commonSituations":"SSTable corruption; reading data written by a tool that does not use Cassandra's collection encoding; type confusion between column metadata and stored bytes.","solutions":["Verify the column type matches the stored value (DESCRIBE table; check type metadata).","Re-read the value; if reproducible, treat the cell as corrupt and rewrite it (scrub/repair).","Ensure the buffer position starts at the value's beginning, not mid-value (a misaligned position flips the sign bit).","Catch MarshalException in read paths and skip/log the corrupt value."],"exampleFix":"// before\nSet<Integer> tags = setSerializer.deserialize(cellValue, ByteBufferAccessor.instance);\n// after\ntry {\n    Set<Integer> tags = setSerializer.deserialize(cellValue.duplicate(), ByteBufferAccessor.instance);\n} catch (MarshalException e) {\n    logger.warn(\"Corrupt set cell ignored: {}\", e.getMessage());\n}","handlingStrategy":"try-catch","validationCode":"// Java\nif (buf.remaining() >= 4) {\n    int n = ByteBufferUtil.toInt(buf.duplicate());\n    if (n < 0) throw new IllegalStateException(\"corrupt set count\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    Set<T> s = setSerializer.deserialize(buf.duplicate(), ByteBufferAccessor.instance);\n} catch (MarshalException e) {\n    log.warn(\"Corrupt set cell: {}\", e.getMessage());\n}","preventionTips":["Start deserialization at the value's start offset, not mid-value","Confirm column metadata type equals the encoding of stored bytes","Treat negative counts as corruption and rewrite the cell"],"tags":["cassandra","serialization","set","deserialization"],"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-14T16:17:12.679Z"}