{"record":{"id":"e2479eb4c44b6699","repo":"apache/cassandra","slug":"expected-4-or-0-byte-int-d","errorCode":null,"errorMessage":"Expected 4 or 0 byte int (%d)","messagePattern":"Expected 4 or 0 byte int \\((.+?)\\)","errorType":"validation","errorClass":"MarshalException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/serializers/Int32Serializer.java","lineNumber":43,"sourceCode":"\npublic class Int32Serializer extends TypeSerializer<Integer>\n{\n    public static final Int32Serializer instance = new Int32Serializer();\n\n    public <V> Integer deserialize(V value, ValueAccessor<V> accessor)\n    {\n        return accessor.isEmpty(value) ? null : accessor.toInt(value);\n    }\n\n    public ByteBuffer serialize(Integer value)\n    {\n        return value == null ? ByteBufferUtil.EMPTY_BYTE_BUFFER : ByteBufferUtil.bytes(value);\n    }\n\n    public <V> void validate(V value, ValueAccessor<V> accessor) throws MarshalException\n    {\n        if (accessor.size(value) != 4 && !accessor.isEmpty(value))\n            throw new MarshalException(String.format(\"Expected 4 or 0 byte int (%d)\", accessor.size(value)));\n    }\n\n    public String toString(Integer value)\n    {\n        return value == null ? \"\" : String.valueOf(value);\n    }\n\n    public Class<Integer> getType()\n    {\n        return Integer.class;\n    }\n}\n","sourceCodeStart":25,"sourceCodeEnd":56,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/serializers/Int32Serializer.java#L25-L56","documentation":"Int32Serializer.validate() requires a serialized int to be exactly 4 bytes (or 0 bytes for empty). Any other length means the bytes cannot be a valid 32-bit integer, so a MarshalException is thrown. This prevents misinterpreting longer/shorter buffers as int values.","triggerScenarios":"Calling Int32Serializer.validate(value, accessor) (directly or via an Int32Type column) with a buffer whose size is neither 4 nor empty — e.g. an 8-byte long, varint-encoded bigint, or 1-byte tinyint written into an int column.","commonSituations":"Writing a Java long (8 bytes) into an int column; using thrift-era varint encoding; client code serializing Integer with a wrong-width buffer; migrations mapping bigint columns to int columns.","solutions":["Serialize ints with the proper 4-byte encoding: ByteBuffer.allocate(4).putInt(value) or the Int32Type serializer.","If values exceed int range or use 8 bytes, change the column type to bigint and use Long serialization.","Check for accidental double-serialization (a ByteBuffer wrapped inside another ByteBuffer), which changes the length.","Pre-write validation: assert buffer.remaining() == 4 || buffer.remaining() == 0."],"exampleFix":"// before\nByteBuffer bytes = ByteBuffer.allocate(8).putLong(value); // column is int\n// after\nByteBuffer bytes = ByteBuffer.allocate(4).putInt(value);","handlingStrategy":"validation","validationCode":"if (buf != null && buf.remaining() != 4 && buf.remaining() != 0) throw new IllegalArgumentException(\"int needs exactly 4 bytes, got \" + buf.remaining());","typeGuard":"boolean isValidInt32Bytes(java.nio.ByteBuffer b) { return b == null || b.remaining() == 0 || b.remaining() == 4; }","tryCatchPattern":"try { int32Type.validate(buf, accessor); } catch (org.apache.cassandra.exceptions.MarshalException e) { throw new IllegalArgumentException(\"bad int bytes: \" + e.getMessage(), e); }","preventionTips":["Use putInt/Int32Type serializer for int columns; use bigint columns for 8-byte values","Check for double-wrapped ByteBuffers in custom pipelines","Assert fixed widths in ETL/migration serializers"],"tags":["cassandra","serialization","type-validation","int"],"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"}