robfig/cron · error
end of range ( ) above maximum ( )
Error message
end of range (%d) above maximum (%d): %s
What it means
Thrown by getRange in parser.go when the end value of a cron field range exceeds the field's maximum. Each field has fixed bounds (e.g. seconds/minutes 0-59, hours 0-23, day-of-month 1-31, month 1-12, day-of-week 0-6), and getRange rejects ranges whose high end overflows them. This prevents silently wrapping or mis-scheduling values that don't exist in the field.
Solutions
- Check the 'above maximum (%d)' value in the error and reduce the range end to the field's ceiling (seconds/minutes 59, hours 23, dom 31, month 12, dow 6)
- Use '7' for Sunday? This library's dow is 0-6, so map 7 to 0
- Validate spec strings from config/user input with cron.Parse at startup so bad values fail fast
- Use '*' for the whole field instead of an explicit max range
Example fix
// before
cron.Parse("0 0 0 * 1-12,13 *") // month max is 12
// after
cron.Parse("0 0 0 * 1-12 *") Defensive patterns
Strategy: validation
Validate before calling
var fieldMax = map[string]int{"second":59,"minute":59,"hour":23,"dom":31,"month":12,"dow":6}
func validRangeEnd(end int, field string) bool { return end <= fieldMax[field] } Try / catch
sched, err := cron.Parse(spec)
if err != nil {
return fmt.Errorf("invalid cron spec %q: %w", spec, err)
} Prevention
- Memorize the ceilings: seconds/minutes 59, hours 23, dom 31, month 12, dow 6
- Map Quartz's dow 7 to 0 when porting specs
- Validate specs from config at startup with a cron.Parse smoke test
When it happens
Trigger: Calling cron.Parse with a spec like '0 60 * * * *' (minute max 59), '0 0 24 * * *' (hour max 23), '0 0 0 1-32 * *' (dom max 31), '0 0 0 * 1-13 *' (month max 12), or '* * * * * 7-8' under standard dow bounds (max 6).
Common situations: Mistaking hours for a 0-24 range (some systems use 1-24); copying Quartz-style 7-for-Sunday dow values into this library where dow maxes at 6; template strings with placeholders replaced by unvalidated config 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
- beginning of range ( ) below minimum ( )
- beginning of range ( ) beyond end of range ( )
- multiple optionals may not be configured
- parser does not accept descriptors
- expected exactly fields, found
AI-assisted analysis of robfig/cron@bc59245fe1 (2026-09-07).
Data as JSON: /api/errors/4ba5e85168d2a6c7.
Report an issue: GitHub.
Appendix: source
Thrown at parser.go:308
return 0, err
}
// Special handling: "N/step" means "N-max/step".
if singleDigit {
end = r.max
}
if step > 1 {
extra = 0
}
default:
return 0, fmt.Errorf("too many slashes: %s", expr)
}
if start < r.min {
return 0, fmt.Errorf("beginning of range (%d) below minimum (%d): %s", start, r.min, expr)
}
if end > r.max {
return 0, fmt.Errorf("end of range (%d) above maximum (%d): %s", end, r.max, expr)
}
if start > end {
return 0, fmt.Errorf("beginning of range (%d) beyond end of range (%d): %s", start, end, expr)
}
if step == 0 {
return 0, fmt.Errorf("step of range should be a positive number: %s", expr)
}
return getBits(start, end, step) | extra, nil
}
// parseIntOrName returns the (possibly-named) integer contained in expr.
func parseIntOrName(expr string, names map[string]uint) (uint, error) {
if names != nil {
if namedInt, ok := names[strings.ToLower(expr)]; ok {
return namedInt, nil
}
}View on GitHub (pinned to bc59245fe1)