{"record":{"id":"904ecd19cdcefece","repo":"apache/cassandra","slug":"expected-8-byte-long-for-time-d","errorCode":null,"errorMessage":"Expected 8 byte long for time (%d)","messagePattern":"Expected 8 byte long for time \\((.+?)\\)","errorType":"validation","errorClass":"MarshalException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/serializers/TimeSerializer.java","lineNumber":74,"sourceCode":"                throw new MarshalException(String.format(\"Unable to make long (for time) from: '%s'\", source), e);\n            }\n        }\n\n        // Last chance, attempt to parse as time string\n        try\n        {\n            return parseTimeStrictly(source);\n        }\n        catch (IllegalArgumentException e1)\n        {\n            throw new MarshalException(String.format(\"(TimeType) Unable to coerce '%s' to a formatted time (long)\", source), e1);\n        }\n    }\n\n    public <V> void validate(V value, ValueAccessor<V> accessor) throws MarshalException\n    {\n        if (accessor.size(value) != 8)\n            throw new MarshalException(String.format(\"Expected 8 byte long for time (%d)\", accessor.size(value)));\n    }\n\n    @Override\n    public boolean shouldQuoteCQLLiterals()\n    {\n        return true;\n    }\n\n    public String toString(Long value)\n    {\n        if (value == null)\n            return \"null\";\n\n        int nano = (int)(value % 1000);\n        value -= nano;\n        value /= 1000;\n        int micro = (int)(value % 1000);\n        value -= micro;","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/serializers/TimeSerializer.java#L56-L92","documentation":"TimeSerializer.validate enforces that a 'time' value occupies exactly 8 bytes (a long of nanoseconds since midnight). This error indicates the binary value has a different length, so it cannot be a valid time encoding.","triggerScenarios":"Binding a 4-byte int, a variable-length string's bytes, or an empty buffer as a time value; deserializing a column whose bytes came from a different type; custom protocol code writing the wrong width.","commonSituations":"Type confusion between int/date columns and time columns after schema changes; hand-built ByteBuffers in test harnesses; drivers misconfiguring codecs.","solutions":["Ensure the value is exactly 8 bytes: ByteBuffer.allocate(8).putLong(nanosSinceMidnight)","Use the driver's time codec / LocalTime mapping instead of raw bytes","Verify the target column type via metadata before binding","Re-check any ETL code that packs values by hand"],"exampleFix":"// before\nByteBuffer v = Bytes.fromHexString(\"0x0000\"); // 2 bytes\n// after\nByteBuffer v = ByteBuffer.allocate(8).putLong(TimeUnit.HOURS.toNanos(13));","handlingStrategy":"type-guard","validationCode":"if (buf == null || buf.remaining() != 8) throw new IllegalArgumentException(\"time value must be exactly 8 bytes, got \" + (buf == null ? 0 : buf.remaining()));","typeGuard":"boolean isWellFormedTimeBytes(ByteBuffer v) { return v != null && v.remaining() == 8; }","tryCatchPattern":"try {\n  serializer.validate(value, byteBufferAccessor);\n} catch (MarshalException e) {\n  throw new DataCorruptionException(\"non-8-byte value in time column\", e);\n}","preventionTips":["Build time payloads with ByteBuffer.allocate(8).putLong(...)","Use driver codecs rather than manual byte packing","Verify column types via metadata before raw binding","Check ETL buffer slicing logic for off-by-width bugs"],"tags":["cassandra","serialization","time","byte-size"],"backgroundTag":"type-mismatch","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"}