cronkit.org
Cron expressions, explained and converted — in your browser

Cron tools › Platforms

Kubernetes CronJob generator

batch/v1 · .spec.timeZone · robfig/cron rules

Fill in the form and copy a CronJob manifest that applies cleanly: the schedule is checked with the rules Kubernetes uses, the name against its 52-character limit, and the next runs are shown in the timeZone you pick.

Manifest

Next runs

Try a schedule

How to generate a Kubernetes CronJob

  1. Give the CronJob a name: lowercase letters, digits and dashes, at most 52 characters.
  2. Type the schedule in five-field cron (or @hourly, @daily and friends). It is checked the way Kubernetes' parser reads it.
  3. Pick a timeZone, or leave it unset to use the kube-controller-manager's zone. Never put TZ= or CRON_TZ= in the schedule itself.
  4. Set the image, command and arguments (one list item per line), then the policies. Fields show their Kubernetes defaults.
  5. Copy or download the YAML and apply it with kubectl apply -f. For a quick test, the kubectl create cronjob line sets only image, schedule, restart policy and command.

CronJob fields and their defaults

FieldDefaultWhat to know
schedulerequiredFive fields; see below. No TZ= prefix.
timeZonekube-controller-manager's zoneAn IANA name such as Europe/Berlin. Stable since Kubernetes v1.27.
concurrencyPolicyAllowAllow, Forbid or Replace.
startingDeadlineSecondsnoneValues under 10 may mean the Job is never scheduled.
successfulJobsHistoryLimit3Successful Jobs kept.
failedJobsHistoryLimit1Failed Jobs kept.
suspendfalsetrue or false.

If more than 100 schedules are missed, Kubernetes creates no Job for them; the generator tells you how long 100 runs of your schedule last. Kubernetes' documentation also asks for Jobs to be idempotent.

The schedule syntax Kubernetes accepts

CronJob schedules are parsed by robfig/cron's standard parser: five fields, names case-insensitive, day-of-week 0-6 (7 is rejected), ? meaning the same as *, and 5/15 meaning 5-59/15. There is no L, W or #, and no @reboot; @yearly/@annually, @monthly, @weekly, @daily/@midnight and @hourly work.

The */2 surprise. When both day fields are set, a CronJob runs when either matches, like Linux cron. But Kubernetes counts only a bare * as "unrestricted", while Linux counts any field that starts with *. So 0 0 */2 * 1 runs on every odd-numbered day and every Monday in Kubernetes, and only on odd-numbered Mondays on Linux. The generator shows the Kubernetes reading and says so. Compare the two with the cron diff.

FAQ

Why is my CronJob rejected with "cannot use TZ or CRON_TZ in schedule"?

Since Kubernetes v1.29, new CronJobs may not carry TZ= or CRON_TZ= in .spec.schedule. Move the zone into .spec.timeZone; the generator offers a one-click fix when it sees the prefix.

What time zone does a CronJob use without timeZone?

The zone of the kube-controller-manager. This page cannot know it, so without a timeZone the run list is shown in UTC.

Why did my CronJob stop creating Jobs after an outage?

When more than 100 schedules have been missed, Kubernetes creates no Job for them. A very frequent schedule reaches 100 quickly: for * * * * * that is 100 minutes.

Can I use 7 for Sunday?

No. Kubernetes accepts day-of-week 0-6 only; write Sunday as 0 or SUN.