{"record":{"id":"0e684759fc4664df","repo":"apache/cassandra","slug":"corrupt-negative-value-length-encountered","errorCode":null,"errorMessage":"Corrupt (negative) value length encountered","messagePattern":"Corrupt \\(negative\\) value length encountered","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/marshal/AbstractType.java","lineNumber":661,"sourceCode":"        return read(ByteBufferAccessor.instance, in, maxValueSize);\n    }\n\n    public byte[] readArray(DataInputPlus in, int maxValueSize) throws IOException\n    {\n        return read(ByteArrayAccessor.instance, in, maxValueSize);\n    }\n\n    public <V> V read(ValueAccessor<V> accessor, DataInputPlus in, int maxValueSize) throws IOException\n    {\n        int length = valueLengthIfFixed;\n\n        if (length >= 0)\n            return accessor.read(in, length);\n        else\n        {\n            int l = in.readUnsignedVInt32();\n            if (l < 0)\n                throw new IOException(\"Corrupt (negative) value length encountered\");\n\n            if (l > maxValueSize)\n                throw new IOException(String.format(\"Corrupt value length %d encountered, as it exceeds the maximum of %d, \" +\n                                                    \"which is set via max_value_size in cassandra.yaml\",\n                                                    l, maxValueSize));\n\n            return accessor.read(in, l);\n        }\n    }\n\n    public void skipValue(DataInputPlus in) throws IOException\n    {\n        int length = valueLengthIfFixed;\n        if (length >= 0)\n            in.skipBytesFully(length);\n        else\n            ByteBufferUtil.skipWithVIntLength(in);\n    }","sourceCodeStart":643,"sourceCodeEnd":679,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/marshal/AbstractType.java#L643-L679","documentation":"AbstractType.read deserializes a value from a DataInputPlus. When the length is VInt-encoded, it is read as an unsigned 32-bit value; if that still decodes negative, the input stream is corrupt, and this IOException is thrown rather than attempting an impossible allocation/read.","triggerScenarios":"Calling read/readBuffer/readArray on a stream whose encoded VInt length decodes to a negative int — i.e. corrupted or misaligned serialization data where the length field bytes are not a valid unsigned VInt32.","commonSituations":"Reading from truncated or corrupted SSTables/commitlog segments; network desynchronization on streaming/messaging connections; a writer and reader disagreeing on the framing format (fixed vs VInt length).","solutions":["Verify integrity of the source data (checksums, scrub) and re-read from a good replica.","Ensure reader and writer use the same protocol version / length encoding (readWithVIntLength vs readLength).","Re-sync the stream or drop the connection if framing is misaligned; cannot recover mid-stream."],"exampleFix":"// ensure matched encoding\n// before: reading a fixed-length stream with the VInt reader\nValue v = type.readWithVIntLength(in);\n// after\nValue v = type.readBuffer(in, headerLength);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch (IOException e) { log.error(\"corrupt value length in input stream\", e); markCorrupt(streamSource); throw new CorruptDataException(e); }","preventionTips":["Enable and monitor checksums/integrity checks on SSTables and streams.","Never reuse the same input stream after a failed read; framing cannot be trusted.","Match writer/reader protocol versions and length-encoding APIs exactly."],"tags":["io","deserialization","data-corruption"],"backgroundTag":"internal-invariant-violation","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"}