{"record":{"id":"e29594f25fc2bab4","repo":"apache/cassandra","slug":"parameter-older-than-timestamp-has-to-be-a-valid-i","errorCode":null,"errorMessage":"Parameter older_than_timestamp has to be a valid instant in ISO format.","messagePattern":"Parameter older_than_timestamp has to be a valid instant in ISO format\\.","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/snapshot/ClearSnapshotTask.java","lineNumber":124,"sourceCode":"        Object olderThan = options.get(\"older_than\");\n        Object olderThanTimestamp = options.get(\"older_than_timestamp\");\n\n        long maxCreatedAt = Clock.Global.currentTimeMillis();\n        if (olderThan != null)\n        {\n            assert olderThan instanceof String : \"it is expected that older_than is an instance of java.lang.String\";\n            maxCreatedAt -= new DurationSpec.LongSecondsBound((String) olderThan).toMilliseconds();\n        }\n        else if (olderThanTimestamp != null)\n        {\n            assert olderThanTimestamp instanceof String : \"it is expected that older_than_timestamp is an instance of java.lang.String\";\n            try\n            {\n                maxCreatedAt = Instant.parse((String) olderThanTimestamp).toEpochMilli();\n            }\n            catch (DateTimeParseException ex)\n            {\n                throw new RuntimeException(\"Parameter older_than_timestamp has to be a valid instant in ISO format.\");\n            }\n        }\n\n        return getClearSnapshotPredicate(tag, Set.of(keyspaceNames), maxCreatedAt, false);\n    }\n\n    /**\n     * Returns a predicate based on which a snapshot will be included for deletion or not.\n     *\n     * @param tag                name of snapshot to remove\n     * @param keyspaces          keyspaces this snapshot belongs to\n     * @param olderThanTimestamp clear the snapshot if it is older than given timestamp\n     * @param includeEphemeral   whether to include ephemeral snapshots as well\n     * @return predicate which filters snapshots on given parameters\n     */\n    static Predicate<TableSnapshot> getClearSnapshotPredicate(String tag,\n                                                              Set<String> keyspaces,\n                                                              long olderThanTimestamp,","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/snapshot/ClearSnapshotTask.java#L106-L142","documentation":"Thrown by getPredicateForCleanedSnapshots when the older_than_timestamp parameter cannot be parsed as an ISO-8601 instant via Instant.parse. The snapshot-clear API expects an absolute timestamp; any malformed or non-ISO string fails before a snapshot deletion predicate is built.","triggerScenarios":"Calling clear-snapshot (nodetool/JMX) with older_than_timestamp set to a value that Instant.parse rejects, e.g. 'yesterday', '2024-01-01' (date only, no time/zone), '1700000000' (epoch seconds), or empty string.","commonSituations":"Operators pass unix epoch seconds or human dates ('2024-01-01', 'now-7d') instead of the required ISO instant like '2024-01-01T00:00:00Z'; scripts build timestamps with the wrong date formatter.","solutions":["Convert the value to a full ISO-8601 instant with trailing 'Z', e.g. date -u -d @1700000000 +%Y-%m-%dT%H:%M:%SZ.","Validate the string with java.time.Instant.parse (or DateTimeFormatter.ISO_INSTANT) before invoking the API.","If only a relative age is intended, omit older_than_timestamp and use the snapshot-age based clearing options instead.","Catch DateTimeParseException around Instant.parse in wrapper scripts and report the exact expected format."],"exampleFix":"// before\nclearSnapshot(\"ks1\", \"tag1\", \"1700000000\");\n// after\nclearSnapshot(\"ks1\", \"tag1\", Instant.ofEpochSecond(1700000000).toString()); // 2023-11-14T22:13:20Z","handlingStrategy":"validation","validationCode":"boolean isValidInstant(String s) { try { Instant.parse(s); return true; } catch (DateTimeParseException | NullPointerException e) { return false; } }","typeGuard":null,"tryCatchPattern":"try { mgr.clearSnapshotsWithTimestamp(isoInstant); } catch (RuntimeException e) { log.error(\"older_than_timestamp must be ISO-8601 instant, e.g. 2024-01-01T00:00:00Z\", e); }","preventionTips":["Always format timestamps with DateTimeFormatter.ISO_INSTANT and a 'Z' suffix","Never pass epoch seconds or human dates directly as older_than_timestamp","Unit-test any script that composes this parameter"],"tags":["snapshot","datetime","invalid-argument-format","nodetool"],"backgroundTag":"invalid-date-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"}