{"record":{"id":"12b736c2989db201","repo":"nats-io/nats-server","slug":"beginning-of-range-d-below-minimum-d-s","errorCode":null,"errorMessage":"beginning of range (%d) below minimum (%d): %s","messagePattern":"beginning of range \\((.+?)\\) below minimum \\((.+?)\\): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cron.go","lineNumber":222,"sourceCode":"\t\tstep = 1\n\tcase 2:\n\t\tstep, err = mustParseInt(rangeAndStep[1])\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\t// Special handling: \"N/step\" means \"N-max/step\".\n\t\tif singleDigit {\n\t\t\tend = r.max\n\t\t}\n\t\tif step > 1 {\n\t\t\textra = 0\n\t\t}\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"too many slashes: %s\", expr)\n\t}\n\n\tif start < r.min {\n\t\treturn 0, fmt.Errorf(\"beginning of range (%d) below minimum (%d): %s\", start, r.min, expr)\n\t}\n\tif end > r.max {\n\t\treturn 0, fmt.Errorf(\"end of range (%d) above maximum (%d): %s\", end, r.max, expr)\n\t}\n\tif start > end {\n\t\treturn 0, fmt.Errorf(\"beginning of range (%d) beyond end of range (%d): %s\", start, end, expr)\n\t}\n\tif step == 0 {\n\t\treturn 0, fmt.Errorf(\"step of range should be a positive number: %s\", expr)\n\t}\n\treturn getBits(start, end, step) | extra, nil\n}\n\n// parseIntOrName returns the (possibly-named) integer contained in expr.\nfunc parseIntOrName(expr string, names map[string]uint) (uint, error) {\n\tif names != nil {\n\t\tif namedInt, ok := names[strings.ToLower(expr)]; ok {\n\t\t\treturn namedInt, nil","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/cron.go#L204-L240","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use the field's valid minimum: months must start at 1 (\"1-12\"), days of week 0-6, minutes/seconds/hours 0-based","Check the numeric start of each '-' range against the field's documented bounds","Use '*' if the full field range is intended"],"exampleFix":"// before (month field)\n expr := \"0-12\"\n// after\n expr := \"1-12\"","handlingStrategy":"validation","validationCode":"var fieldMins = map[int]uint{0: 0, 1: 0, 2: 0, 3: 1, 4: 1, 5: 0} // sec,min,hour,dom,mon,dow\n// check range starts >= fieldMins[fieldIdx] before scheduling","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Months are 1-12 (not 0-based) in this parser","Document field bounds next to schedule constants"],"tags":["cron","parsing","range-validation"],"backgroundTag":"invalid-cron-expression","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}