Lintcron above accepts three cron expression variants: POSIX five-field, six-field with seconds, and seven-field Quartz. The reference below covers the field ranges, special characters, predefined nicknames, and common-failure shapes that appear when an expression is rejected.
| Variant | Field count | Parser library | Where it shows up | Canonical example |
|---|---|---|---|---|
| POSIX / Vixie | 5 | Vixie cron, ISC cron, dcron | /etc/crontab, user crontabs, anacron | 0 9 * * 1-5 |
| With seconds | 6 | node-cron, cron-validate | Node.js schedulers, some Spring jobs | 0 0 9 * * 1-5 |
| Quartz 7-field | 7 | Quartz, cron-utils, cRonstrue | Java/Spring schedulers, Elastic Job | 0 0 9 ? * MON-FRI 2026 |
| robfig Go | 5 or 6 | robfig/cron | Kubernetes CronJob, Go services | 0 9 * * 1-5 |
| AWS EventBridge | 6 (no seconds) | EventBridge schedule expression | EventBridge rules, AWS Scheduler | 0 12 ? * MON-FRI * |
| GitHub Actions | 5 | YAML schedule.cron | .github/workflows/*.yml | 0 9 * * 1-5 |
| Position | Field | Range | String aliases | Special chars |
|---|---|---|---|---|
| 1 | minute | 0–59 | none | * , - / |
| 2 | hour | 0–23 | none | * , - / |
| 3 | day-of-month | 1–31 | none | * , - / |
| 4 | month | 1–12 | JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC | * , - / |
| 5 | day-of-week | 0–7 (0 and 7 are Sunday) | SUN MON TUE WED THU FRI SAT | * , - / |
0 and 7 in the day-of-week field both resolve to Sunday for historical Vixie cron compatibility.*/5) are a Vixie extension, not part of POSIX.2-1992 §3, but every Unix daemon accepts them.| Position | Field | Range | String aliases | Special chars |
|---|---|---|---|---|
| 1 | second | 0–59 | none | * , - / |
| 2 | minute | 0–59 | none | * , - / |
| 3 | hour | 0–23 | none | * , - / |
| 4 | day-of-month | 1–31 | none | * , - / |
| 5 | month | 1–12 | JAN–DEC | * , - / |
| 6 | day-of-week | 0–6 or 1–7 (parser-dependent) | SUN–SAT | * , - / |
@Scheduled(cron = ...) defaults to six-field with seconds first; pasting a Unix crontab line directly produces a parser error.cron-validate place seconds first; the Quartz six-field form drops the year, not the seconds.| Position | Field | Range | String aliases | Special chars |
|---|---|---|---|---|
| 1 | second | 0–59 | none | * , - / |
| 2 | minute | 0–59 | none | * , - / |
| 3 | hour | 0–23 | none | * , - / |
| 4 | day-of-month | 1–31 | none | * ? , - / L W |
| 5 | month | 1–12 | JAN–DEC | * , - / |
| 6 | day-of-week | 1–7 (1 = Sunday) | SUN–SAT | * ? , - / L # |
| 7 | year | 1970–2099 | none | * , - / |
? must appear in exactly one of day-of-month or day-of-week; setting both to non-? values is a parser error.| Dialect | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| Vixie / ISC / robfig | Sun | Mon | Tue | Wed | Thu | Fri | Sat | Sun |
| Quartz | n/a | Sun | Mon | Tue | Wed | Thu | Fri | Sat |
| node-cron (6-field) | Sun | Mon | Tue | Wed | Thu | Fri | Sat | n/a |
| GitHub Actions | Sun | Mon | Tue | Wed | Thu | Fri | Sat | Sun |
| AWS EventBridge | n/a | Sun | Mon | Tue | Wed | Thu | Fri | Sat |
A step interval is written <value>/<step> where <value> is *, a single number, or a range, and <step> is the increment.
| Pattern | Reads as |
|---|---|
| */5 | every 5 starting at 0 |
| 0/5 | every 5 starting at 0 (Quartz form) |
| 7/30 | every 30 starting at 7 |
| 10-50/5 | every 5 from 10 to 50 inclusive |
| 1-31/2 | every other day-of-month |
Lists combine with steps: 0,30 9-17/2 * * 1-5 reads as “minute 0 and 30, every two hours from 9 to 17, weekdays.” Step values larger than the field maximum collapse to a single fire per cycle. GitHub Actions caps the minute step at 5; */3 * * * * in a workflow file silently rounds up to */5.
| Char | Meaning | Example | Reads as | Supported in |
|---|---|---|---|---|
| * | any value | * * * * * | every minute | all variants |
| , | value list | 0 9,17 * * * | 9:00 AM and 5:00 PM | all variants |
| - | inclusive range | 0 9 * * 1-5 | weekdays at 9:00 AM | all variants |
| / | step interval | */15 * * * * | every 15 minutes | all variants |
| ? | no specific value | 0 0 9 ? * MON-FRI | weekdays at 9:00 AM | Quartz, EventBridge |
| L | last | 0 0 0 L * ? | midnight on the last day of the month | Quartz, EventBridge |
| W | nearest weekday | 0 0 0 15W * ? | nearest weekday to the 15th | Quartz, EventBridge |
| LW | last weekday | 0 0 0 LW * ? | last weekday of the month | Quartz |
| # | nth weekday | 0 0 9 ? * 6#3 | third Friday at 9:00 AM | Quartz, EventBridge |
| nL (DOW) | last weekday-of-month | 0 0 12 ? * 6L | last Friday at noon | Quartz |
| Nickname | Expands to | Vixie / ISC | robfig (K8s) | GitHub Actions | Quartz | EventBridge |
|---|---|---|---|---|---|---|
| @yearly | 0 0 1 1 * | yes | yes | no | no | no |
| @annually | 0 0 1 1 * | yes | yes | no | no | no |
| @monthly | 0 0 1 * * | yes | yes | no | no | no |
| @weekly | 0 0 * * 0 | yes | yes | no | no | no |
| @daily | 0 0 * * * | yes | yes | no | no | no |
| @midnight | 0 0 * * * | yes | yes | no | no | no |
| @hourly | 0 * * * * | yes | yes | no | no | no |
| @reboot | run once at startup | yes | no | no | no | no |
| @every <duration> | every Go duration | no | yes | no | no | no |
@every 1h30m is a robfig extension only, accepted by Kubernetes CronJob since cron v3.
| Expression | Variant | What it fires |
|---|---|---|
| */5 * * * * | 5-field | every 5 minutes |
| 0 * * * * | 5-field | top of every hour |
| 0 9 * * 1-5 | 5-field | weekdays at 9:00 AM |
| 0 0 1 * * | 5-field | midnight on the 1st of each month |
| 0 0 * * 0 | 5-field | every Sunday at midnight |
| 0 0 9 ? * MON-FRI | 6-field Quartz | weekdays at 9:00 AM, Quartz dialect |
| 0 0 12 L * ? | 6-field Quartz | noon on the last day of each month |
| 0 0 0 ? * 6#3 | 6-field Quartz | midnight on the third Friday |
| 0 15 10 ? * MON-FRI 2026 | 7-field Quartz | weekdays at 10:15 AM in 2026 only |
| cron(0 12 * * ? *) | EventBridge | noon every day (note the cron() wrapper) |
| rate(5 minutes) | EventBridge | every 5 minutes (rate, not cron) |
| Symptom | Cause | Fix |
|---|---|---|
| "Expression contains 5 fields, expected 6" | Pasting Unix cron into a Quartz-only system | Prefix with seconds: 0 0 9 * * MON-FRI |
| "Day field set twice" on EventBridge or Quartz | Both day-of-month and day-of-week are restricted | Replace the unused field with ? |
| Job fires more often than expected on weekdays | Both DOM and DOW restricted in Vixie cron (logical OR) | Use only one field; leave the other * |
| */3 * * * * runs every five minutes on GitHub Actions | Actions silently caps the minute step at 5 | Use */5 or accept the five-minute floor |
| Kubernetes rejects 0 0 9 ? * MON-FRI | robfig parser does not accept ? | Replace ? with * and drop the seconds field |
| "Year 2200 out of range" | Quartz year field caps at 2099 | Stop scheduling that far out, or omit the year |
| Expression valid but never fires | Day-of-month references a date the month does not have (e.g., 0 0 31 2 *) | Use L if Quartz available; otherwise split per-month entries |
| AWS rejects 0 12 * * MON-FRI * | EventBridge requires ? in DOM or DOW | cron(0 12 ? * MON-FRI *) |
| @daily rejected by Quartz | Quartz does not support named macros | Expand to 0 0 0 * * ? |
| Wrong fire time on GitHub Actions | Actions runs in UTC, not the repo's local timezone | Convert local time to UTC before writing the cron |
| Day-of-week off by one between systems | Quartz uses 1 = Sunday, Vixie uses 0 = Sunday | Use string aliases (MON, TUE, ...) to avoid the offset |
misfireInstruction, K8s startingDeadlineSeconds).concurrencyPolicy: Forbid | Allow | Replace for overlapping runs.PATH, SHELL, MAILTO, and other variables set in Vixie cron's header.flock, distributed locks, and avoiding duplicate runs when several hosts share a schedule.