nats-io/nats-server · error

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

Error message

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

What it means

After parsing a cron field's range, getRange checks the start against the field's minimum (e.g. 0 for minutes, 1 for months). A start value below the field's legal minimum is rejected with the offending expression echoed back.

Source

Thrown at server/cron.go:222

		step = 1
	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 {
			return namedInt, nil

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Use the field's valid minimum: months must start at 1 ("1-12"), days of week 0-6, minutes/seconds/hours 0-based
  2. Check the numeric start of each '-' range against the field's documented bounds
  3. Use '*' if the full field range is intended

Example fix

// before (month field)
 expr := "0-12"
// after
 expr := "1-12"
Defensive patterns

Strategy: validation

Validate before calling

var fieldMins = map[int]uint{0: 0, 1: 0, 2: 0, 3: 1, 4: 1, 5: 0} // sec,min,hour,dom,mon,dow
// check range starts >= fieldMins[fieldIdx] before scheduling

Prevention

When it happens

Trigger: A range whose start is below the field minimum, e.g. seconds/minutes "0-59" is fine but month field "0-12" (months are 1-12) triggers it via parseCron -> getField -> getRange.

Common situations: Using 0-based months in a cron expression (most cron uses 1-12); writing minute ranges like "60-70" style errors elsewhere; mixing up day-of-week (0-6) with day-of-month ranges.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/12b736c2989db201. Report an issue: GitHub.