robfig/cron · error

beginning of range ( ) below minimum ( )

Error message

beginning of range (%d) below minimum (%d): %s

What it means

Thrown by getRange in parser.go when the start value of a cron field range is below the field's minimum. Each cron field (second, minute, hour, dom, month, dow) has a bounds struct with a min/max, and getRange validates the parsed range against those bounds before building the bit set. E.g. a range starting at 0 in the day-of-month or month field (both 1-based) fails because their minimum is 1.

Solutions

  1. Read the error's 'below minimum (%d)' value to see the field's floor (e.g. 1 for month/dom) and change the range start to that minimum or higher
  2. Use '*' or '?' instead of an explicit range when you mean the full field
  3. If generating specs in code, clamp the range start to the field's bounds before formatting the string
  4. Remember this library's month and day-of-month fields are 1-based, unlike some 0-based APIs

Example fix

// before
cron.Parse("0 0 0 0-15 * *") // dom min is 1
// after
cron.Parse("0 0 0 1-15 * *")
Defensive patterns

Strategy: validation

Validate before calling

func validRangeStart(start, fieldMin int) bool { return start >= fieldMin }
// e.g. month/dom are 1-based: check start >= 1 before building "start-end" strings

Try / catch

sched, err := cron.Parse(spec)
if err != nil {
	return fmt.Errorf("invalid cron spec %q: %w", spec, err)
}

Prevention

When it happens

Trigger: Calling cron.Parse with a spec where a range's start is below the field minimum: '0-5 0 0 0 1 *' or '0 0 0 0-5 * *' (dom min is 1), '* * * * 0-11 *' is fine but '0 0 0 * 0 *' (month min is 1) fails. Any schedule string like 'X-Y/step' where X < field min.

Common situations: Copy-pasting 0-based values into 1-based fields (month, day-of-month) from programming contexts where month indexes start at 0; hand-editing crontab entries; generating specs programmatically with an off-by-one loop starting at 0.

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


AI-assisted analysis of robfig/cron@bc59245fe1 (2026-09-07). Data as JSON: /api/errors/a79cc2084a9a720c. Report an issue: GitHub.

Appendix: source

Thrown at parser.go:305

	case 2:
		step, err = mustParseInt(rangeAndStep[1])
		if err != nil {
			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 {

View on GitHub (pinned to bc59245fe1)