Cron tools › Explain / Test
Cron validator
Is this cron expression valid — and does it mean the same thing everywhere it is valid? The validator parses one expression as 13 schedulers would, shows the first error or the plain-English meaning for each, and flags the dialects where the same text runs at different times.
Per dialect
Next 20 runs, by reading
Try one
How to validate a cron expression
- Paste the expression exactly as it appears in your config — five fields, six with seconds, an AWS
cron(…)or an@shortcut. - Read the verdict: how many of the 13 dialects accept it, and how many different schedules those acceptances add up to.
- Find your scheduler's row. An invalid row shows the first error; a valid row shows what it means there, with the dialect's warnings.
- Look for means something different here. It marks dialects whose next runs differ from the Unix cron reading (or, if Unix cron rejects the text, from the first dialect that accepts it).
- Where Unix cron accepts the expression, a row can offer a version written for that dialect with the same runs. Copy it, then check the table of next runs.
Three differences that change the meaning
Day-of-month and day-of-week together. When both are restricted, Vixie cron, Kubernetes and Google Cloud
Scheduler run on days that match either; Jenkins, Spring, Azure, Celery and node-cron require both; Quartz and
AWS require one of them to be ?; Vercel requires one to be *. GitHub Actions and Cloudflare do not
document the rule.
What counts as unrestricted. Vixie cron looks at the first character: a field that starts with *
counts as unrestricted, so 0 0 */2 * 1 means "odd-numbered days that are Mondays". Kubernetes only treats a bare
* or ? that way, so the same string there means "every odd-numbered day, and every Monday".
Day-of-week numbers. Quartz, AWS and Cloudflare Workers number the week 1 = Sunday … 7 = Saturday, so
1-5 from a Linux crontab is Sunday to Thursday there. Linux cron, Spring, node-cron, Jenkins and Cloud Scheduler
accept 0-7 with both 0 and 7 meaning Sunday; Kubernetes, Azure and Celery accept only 0-6.
What each dialect accepts
| Dialect | Fields | Day of week | Extras and limits |
|---|---|---|---|
| Unix cron (Vixie, cronie) | 5 | 0-7, SUN-SAT | @reboot and the other @ shortcuts; no L W # |
| GitHub Actions | 5 | 0-6, SUN-SAT | No @ shortcuts; shortest interval 5 minutes |
| Kubernetes CronJob | 5 | 0-6 (7 rejected) | ? = *; shortcuts except @reboot; no L W # |
| Jenkins | 5 | 0-7, digits only | H hashed values; @ aliases expand through H |
| Quartz | 6 or 7 (seconds first, optional year) | 1-7 = SUN-SAT | Exactly one day field must be ?; L W # LW nL |
| AWS EventBridge | 6 in cron(…), year last | 1-7, SUN-SAT | ? required in one day field; L W #; no / in day of week |
Spring @Scheduled | 6 (seconds first) | 0-7, MON-SUN | ? = *; L W #; @ shortcuts |
| Azure Functions (NCRONTAB) | 6 (5 also supported) | 0-6 | No ? L W # |
| node-cron | 5 or 6 (seconds first) | 0-7 | ? L W #; shortcuts except @reboot |
Celery crontab.from_string() | 5 | 0-6 (7 raises) | Day fields AND |
| Google Cloud Scheduler | 5 | 0-6, SUN-SAT or 7 | No L |
| Vercel | 5 | 0-6, no names | One day field must be *; always UTC |
| Cloudflare Workers | 5 | 1-7 (1 = Sunday) | L W #; UTC |
To convert between two of them with the day numbers and ? handled for you, use cron to
Quartz or Quartz to cron; to see two schedules side by side run by run, use the
cron diff.
FAQ
Why is my Linux cron expression invalid in Quartz and AWS?
Two reasons, usually both. Quartz starts with a seconds field and AWS ends with a year field, so five fields are the wrong
count. And both need ? in either day-of-month or day-of-week, because they do not support restricting both. Fixing
only those is not enough when the day of week has numbers: their week starts at 1 = Sunday.
What does "means something different here" compare?
The next 100 run times in UTC, computed with each dialect's own rules, against the Unix cron reading. Dialects with identical runs share a letter (A, B, …); a row with a different letter runs at other times. The table under the dialects shows the first 20 runs of each reading and highlights the ones the first reading does not have.
Why are GitHub Actions and Cloudflare marked with a warning when both day fields are set?
Neither documents whether day-of-month and day-of-week combine with AND or OR. The validator shows one plausible reading, but
the safe choice is to keep one of the two fields *.
How does the Jenkins row handle H?
H is replaced by a value hashed from the job's full name, so the same spec runs at different minutes for different
jobs. Type the job name in the box to see the times Jenkins would pick for it; the other dialects reject H.