{"record":{"id":"d85df4fd4b8892e9","repo":"apache/cassandra","slug":"the-duration-must-have-a-millisecond-precision-wa","errorCode":null,"errorMessage":"The duration must have a millisecond precision. Was: %s","messagePattern":"The duration must have a millisecond precision\\. Was: (.+?)","errorType":"exception","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/marshal/TimestampType.java","lineNumber":173,"sourceCode":"    {\n        return this == otherType || otherType == DateType.instance || otherType == LongType.instance;\n    }\n\n    public CQL3Type asCQL3Type()\n    {\n        return CQL3Type.Native.TIMESTAMP;\n    }\n\n    public TypeSerializer<Date> getSerializer()\n    {\n        return TimestampSerializer.instance;\n    }\n\n    @Override\n    protected void validateDuration(Duration duration)\n    {\n        if (!duration.hasMillisecondPrecision())\n            throw invalidRequest(\"The duration must have a millisecond precision. Was: %s\", duration);\n    }\n\n    @Override\n    public ByteBuffer getMaskedValue()\n    {\n        return MASKED_VALUE;\n    }\n}\n","sourceCodeStart":155,"sourceCodeEnd":182,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/marshal/TimestampType.java#L155-L182","documentation":"TimestampType stores instants with millisecond precision. When a duration value is validated for a timestamp column, the duration must have millisecond precision; durations with precision finer than milliseconds (micro/nanoseconds) are rejected with this invalid-request error.","triggerScenarios":"Inserting or binding a Duration into a 'timestamp' column where duration.hasMillisecondPrecision() is false — i.e. the duration includes sub-millisecond components (nanos not a multiple of 1,000,000).","commonSituations":"Clients generating durations from java.time with nanosecond resolution (e.g. Duration.ofNanos) and binding them to timestamp columns; migrating high-resolution timing data from other systems into Cassandra timestamps.","solutions":["Round or truncate the duration to whole milliseconds before binding (e.g. Duration.ofMillis(d.toMillis())).","Adjust the literal to millisecond precision, e.g. PT0.123S instead of PT0.123456S.","If sub-millisecond precision is required, store the value as a different type (e.g. duration or a custom encoding)."],"exampleFix":"// before\nDuration d = Duration.ofNanos(1_500_123L);\nstmt.set(0, d); // rejected\n// after\nstmt.set(0, Duration.ofMillis(d.toMillis()));","handlingStrategy":"validation","validationCode":"// Java (driver): ensure millisecond precision before binding to a timestamp column\nif (!duration.hasMillisecondPrecision())\n    duration = Duration.ofMillis(duration.toMillis()); // truncate to milliseconds","typeGuard":null,"tryCatchPattern":"try {\n    session.execute(stmt.bind(duration));\n} catch (InvalidQueryException e) {\n    if (e.getMessage().contains(\"millisecond precision\")) {\n        // truncate duration to millis and retry\n    }\n}","preventionTips":["Truncate nanosecond-resolution durations with Duration.ofMillis(d.toMillis()) before binding.","Avoid constructing durations from nanosecond sources when targeting timestamp columns.","Keep duration literals at or coarser than millisecond granularity (e.g. PT0.123S)."],"tags":["cql","duration","timestamp","type-validation"],"backgroundTag":"invalid-duration-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"}