Kubernetes CronJob schedule checker

Paste a Kubernetes CronJob schedule to see it in plain English, the next runs in its timeZone, and syntax Kubernetes rejects, like 7 for Sunday or TZ=.

In plain English
—

Next runs

CronJob manifest

Kubernetes cron syntax and common schedules

.spec.schedule takes five fields. Each one accepts a value, a list (1,15), a range (1-5), a step (*/10 or 0-30/5) or * for every value, and ? means the same as *.

FieldAllowed valuesExample
minute0–59*/15
hour0–239-17
day of month1–311,15
month1–12 or jan–decjan-mar
day of week0–6 or sun–sat (0 = Sunday)mon-fri

There is no seconds field. Quartz extras such as L, W and # fail validation, and so does 7 for Sunday. Lowercase macros such as @daily and @weekly work, and all but @hourly run at midnight; @DAILY fails validation. Writing a GitHub workflow instead? Use the GitHub Actions cron schedule checker.

To runSchedule
every 5 minutes*/5 * * * *
every hour0 * * * * or @hourly
every day at 03:000 3 * * *
weekdays at 09:000 9 * * 1-5
Mondays at 03:000 3 * * 1
the 1st of each month at 00:000 0 1 * * or @monthly

Worked example: timeZone for a 06:30 report in Paris

30 6 * * 1-5 runs at 06:30 Monday to Friday. Without timeZone, that means 06:30 in the controller's time zone. On GKE that is UTC, which is 07:30 in Paris in winter and 08:30 in summer. Set timeZone to keep it at 06:30 local time all year:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: morning-report
spec:
  schedule: "30 6 * * 1-5"
  timeZone: "Europe/Paris"

Do not prefix the schedule with TZ=Europe/Paris or CRON_TZ=: Kubernetes rejects it. To see the next runs, load this example in the tool.

Pitfall: daylight saving time

Kubernetes computes run times with the robfig/cron library, which kubernetes.io links to for the schedule format. In a time zone with daylight saving, a run inside the hour that clocks skip, such as 02:30 in Europe/Paris on the last Sunday of March, does not happen that day. A run inside the hour that repeats when clocks go back happens twice. With concurrencyPolicy: Forbid, the second one is skipped if the first is still running. In zones that change clocks at midnight or by 30 minutes, such as America/Santiago or Australia/Lord_Howe, the library can also skip or add runs at other times that day. The tool warns about all of these for the next 12 months. Pick a time it does not warn about, or set timeZone to Etc/UTC.

Pitfall: day of month and day of week together

When both day fields are set, the job runs when either one matches. 0 0 13 * 5 runs on every 13th and on every Friday, not only on Friday the 13th. Kubernetes also counts a step such as */5 as set, so 0 0 */5 * 1 runs on the 1st, 6th, 11th and so on, and on every Monday.

FAQ

What time zone does a Kubernetes CronJob use?

The one in .spec.timeZone, if you set it: an IANA name such as Europe/Paris or Etc/UTC. The field has been stable since Kubernetes 1.27. Without it, the kube-controller-manager reads the schedule in its own local time zone, which you often cannot see on a managed cluster; GKE documents UTC. Set timeZone so the schedule does not depend on how the controller is configured.

Can I put TZ= or CRON_TZ= in the schedule?

No. Kubernetes has never officially supported TZ or CRON_TZ inside .spec.schedule, and current versions reject a schedule that contains them with a validation error. Move the zone to the timeZone field: TZ=Europe/Paris 0 9 * * * becomes the schedule 0 9 * * * with timeZone Europe/Paris. Paste the old form into this tool and it offers that fix.

Is 7 Sunday in a Kubernetes cron schedule?

No. Day of week runs from 0 (Sunday) to 6 (Saturday), or sun to sat. Many cron implementations also accept 7 for Sunday, but the parser Kubernetes uses rejects it, so 0 0 * * 7 and 0 0 * * 5-7 fail validation. Use 0 or sun, and write Friday to Sunday as 5,6,0.

How do I run a Kubernetes CronJob every 5 minutes?

Use the schedule */5 * * * *. It runs at minutes 0, 5, 10 and so on of every hour, in the CronJob time zone. The shortest interval a five-field schedule can express is one minute (* * * * *), because there is no seconds field. The parser Kubernetes uses also accepts @every 5m, but kubernetes.io does not document it, and it counts 5 minutes from the last run instead of following the clock.

Why did my CronJob run twice or not at all?

The Kubernetes docs say a CronJob creates a Job approximately once per scheduled time, and in some circumstances two Jobs or none are created, so Jobs should be idempotent. Daylight saving also causes both: in a time zone with DST, a run inside the hour that clocks skip does not happen, and a run inside the hour that repeats when clocks go back happens twice. With concurrencyPolicy: Forbid, a run is also skipped while the previous Job is still running.

What does "too many missed start times" mean?

The CronJob controller counts how many scheduled times it missed since the last one it ran, for example while the CronJob was suspended or the controller was down. Above 100 it records a warning, shown by kubectl describe cronjob: too many missed start times. Set or decrease .spec.startingDeadlineSeconds or check clock skew. The CronJob is not stopped. With startingDeadlineSeconds set, the controller only counts misses inside that window, so a value like 300 keeps the count far below 100 for any five-field schedule.

More tools