{"record":{"id":"2d7f3afa222ed88e","repo":"apache/cassandra","slug":"hour-out-of-bounds","errorCode":null,"errorMessage":"Hour out of bounds.","messagePattern":"Hour out of bounds\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/functions/types/ParseUtils.java","lineNumber":411,"sourceCode":"        long second;\n        long a_nanos = 0;\n\n        String formatError = \"Timestamp format must be hh:mm:ss[.fffffffff]\";\n        String zeros = \"000000000\";\n\n        if (str == null) throw new IllegalArgumentException(formatError);\n        str = str.trim();\n\n        // Parse the time\n        int firstColon = str.indexOf(':');\n        int secondColon = str.indexOf(':', firstColon + 1);\n\n        // Convert the time; default missing nanos\n        if (firstColon > 0 && secondColon > 0 && secondColon < str.length() - 1)\n        {\n            int period = str.indexOf('.', secondColon + 1);\n            hour = Integer.parseInt(str.substring(0, firstColon));\n            if (hour < 0 || hour >= 24) throw new IllegalArgumentException(\"Hour out of bounds.\");\n\n            minute = Integer.parseInt(str.substring(firstColon + 1, secondColon));\n            if (minute < 0 || minute >= 60) throw new IllegalArgumentException(\"Minute out of bounds.\");\n\n            if (period > 0 && period < str.length() - 1)\n            {\n                second = Integer.parseInt(str.substring(secondColon + 1, period));\n                if (second < 0 || second >= 60) throw new IllegalArgumentException(\"Second out of bounds.\");\n\n                nanos_s = str.substring(period + 1);\n                if (nanos_s.length() > 9) throw new IllegalArgumentException(formatError);\n                if (!Character.isDigit(nanos_s.charAt(0))) throw new IllegalArgumentException(formatError);\n                nanos_s = nanos_s + zeros.substring(0, 9 - nanos_s.length());\n                a_nanos = Integer.parseInt(nanos_s);\n            }\n            else if (period > 0) throw new ParseException(formatError, -1);\n            else\n            {","sourceCodeStart":393,"sourceCodeEnd":429,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/functions/types/ParseUtils.java#L393-L429","documentation":"parseTime validated the hour component of the time string and found it outside the valid range 0-23. The CQL `time` type represents a time of day, so any hour >= 24 (or negative) is rejected with this IllegalArgumentException.","triggerScenarios":"Calling ParseUtils.parseTime(\"24:00:00\"), \"25:15:30\", \"99:00:00\" or any negative hour such as \"-1:00:00\" — the hour substring before the first colon parses to an int outside [0, 23].","commonSituations":"Durations encoded as times (\"30:00:00\" meaning 30 hours), 24 as end-of-day from midnight-inclusive ranges, clock data in 1-12 or 1-24 conventions, or off-by-one generation of hour values.","solutions":["Clamp or convert the hour: map 24:00:00 to 23:59:59.999999999 or wrap modulo 24 if the value represents a duration.","Validate hour <= 23 before calling parseTime.","If it is a duration, use the CQL `duration` type / a duration parser instead of `time`.","Catch IllegalArgumentException and report which component was out of bounds."],"exampleFix":"// before\nlong nanos = ParseUtils.parseTime(\"24:00:00\"); // throws\n// after\nString s = \"24:00:00\";\nif (s.startsWith(\"24:\")) s = \"23:59:59.999999999\"; // end-of-day convention\nlong nanos = ParseUtils.parseTime(s);","handlingStrategy":"validation","validationCode":"int hour = Integer.parseInt(s.substring(0, s.indexOf(':')));\nif (hour < 0 || hour > 23) throw new IllegalArgumentException(\"hour must be 0-23: \" + hour);","typeGuard":null,"tryCatchPattern":"try { return ParseUtils.parseTime(s); }\ncatch (IllegalArgumentException e) { log.warn(\"Invalid hour in time '{}'\", s); throw e; }","preventionTips":["Clamp hours from duration-like sources modulo 24 or reject them explicitly","Use 24:00:00 only as a display convention, never as parser input","Use the duration type for elapsed-time values"],"tags":["parsing","time","range-check","illegal-argument"],"backgroundTag":"value-out-of-range","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"}