apache/cassandra · error · IllegalArgumentException
Hour out of bounds.
Error message
Hour out of bounds.
What it means
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.
Source
Thrown at src/java/org/apache/cassandra/cql3/functions/types/ParseUtils.java:411
long second;
long a_nanos = 0;
String formatError = "Timestamp format must be hh:mm:ss[.fffffffff]";
String zeros = "000000000";
if (str == null) throw new IllegalArgumentException(formatError);
str = str.trim();
// Parse the time
int firstColon = str.indexOf(':');
int secondColon = str.indexOf(':', firstColon + 1);
// Convert the time; default missing nanos
if (firstColon > 0 && secondColon > 0 && secondColon < str.length() - 1)
{
int period = str.indexOf('.', secondColon + 1);
hour = Integer.parseInt(str.substring(0, firstColon));
if (hour < 0 || hour >= 24) throw new IllegalArgumentException("Hour out of bounds.");
minute = Integer.parseInt(str.substring(firstColon + 1, secondColon));
if (minute < 0 || minute >= 60) throw new IllegalArgumentException("Minute out of bounds.");
if (period > 0 && period < str.length() - 1)
{
second = Integer.parseInt(str.substring(secondColon + 1, period));
if (second < 0 || second >= 60) throw new IllegalArgumentException("Second out of bounds.");
nanos_s = str.substring(period + 1);
if (nanos_s.length() > 9) throw new IllegalArgumentException(formatError);
if (!Character.isDigit(nanos_s.charAt(0))) throw new IllegalArgumentException(formatError);
nanos_s = nanos_s + zeros.substring(0, 9 - nanos_s.length());
a_nanos = Integer.parseInt(nanos_s);
}
else if (period > 0) throw new ParseException(formatError, -1);
else
{View on GitHub (pinned to 88fd0f6a0e)
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.
Example fix
// before
long nanos = ParseUtils.parseTime("24:00:00"); // throws
// after
String s = "24:00:00";
if (s.startsWith("24:")) s = "23:59:59.999999999"; // end-of-day convention
long nanos = ParseUtils.parseTime(s); Defensive patterns
Strategy: validation
Validate before calling
int hour = Integer.parseInt(s.substring(0, s.indexOf(':')));
if (hour < 0 || hour > 23) throw new IllegalArgumentException("hour must be 0-23: " + hour); Try / catch
try { return ParseUtils.parseTime(s); }
catch (IllegalArgumentException e) { log.warn("Invalid hour in time '{}'", s); throw e; } Prevention
- 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
When it happens
Trigger: 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].
Common situations: 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.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Minute out of bounds.
- Second out of bounds.
- Timestamp format must be hh:mm:ss[.fffffffff]
- Unable to convert '%s' to a duration
- Unknown duration symbol '%s'
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/2d7f3afa222ed88e.
Report an issue: GitHub.