Kubernetes CronJob Helper
Edit a CronJob schedule with a live plain-English readout, timezone-aware next runs and a ready-to-apply manifest — entirely on this device.
The batch/v1 manifest appears here once the schedule parses.
Press ? for shortcuts
Do it offline:$ kubectl create cronjob hello --image=busybox:1.36 --schedule="*/5 * * * *" --dry-run=client -o yaml
How to use it
- Enter the schedule — five fields or a macro; the sentence and runs update as you type.
- Pick a zone for spec.timeZone, or leave it unset and read runs under the stated UTC assumption.
- Set name, image and the policy fields you need; each control explains itself beside the input.
- Copy the manifest or download cronjob.yaml, then apply it with kubectl.
Type a five-field schedule — or a macro like @daily — and read it back as a plain sentence, the next five run instants, and a complete batch/v1 CronJob manifest. Set spec.timeZone and the page names the exact dates daylight saving will skip or double a run. Everything is computed on this device; nothing you type is transmitted.
How it works
The grammar is five-field cron — minute 0–59, hour 0–23, day of month 1–31, month 1–12 or JAN–DEC, day of week 0–6 or SUN–SAT — plus five macros that expand to plain fields first. With both day fields restricted, cron fires on either match, and a note says so.
spec.timeZone pins the schedule to an IANA zone; unset, it follows the kube-controller-manager process. In a daylight-saving zone, a wall-clock schedule can land in the skipped hour (no run) or the repeated hour (two runs); the scan prints the exact dates.
The manifest is a complete batch/v1 object with one container; its pod template sets restartPolicy: OnFailure because a Job accepts only OnFailure or Never. Every scalar is quoted and escaped, so the YAML parses back to exactly what the form holds.
Examples
*/5 * * * *sentence Every 5 minutes, every hour, every day
next runs 2026-08-15 00:05 UTC · 2026-08-15 00:10 UTC · 2026-08-15 00:15 UTC
note spec.timeZone is unset, so Kubernetes interprets this schedule in the time zone of the kube-controller-manager process — whatever zone that machine runs in. The runs below assume UTC.
apiVersion: batch/v1
kind: CronJob
metadata:
name: "hello-cron"
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: "hello-cron"
image: "busybox:1.36"
restartPolicy: OnFailureThe starter state: every five minutes, zone unset. The chip beneath the sentence is the page's most consequential line, and the manifest is complete enough to apply.
30 2 * * *zone America/New_York
sentence At 02:30 in America/New_York, every day
next runs 2026-08-15 06:30 UTC · 2026-08-16 06:30 UTC · 2026-08-17 06:30 UTC
advisory Clocks in America/New_York jump forward on 2027-03-14 (02:00 → 03:00 local time); a run scheduled in that skipped window may not run that day.
zone America/Sao_Paulo
sentence At 02:30 in America/Sao_Paulo, every day
next runs 2026-08-15 05:30 UTC · 2026-08-16 05:30 UTC · 2026-08-17 05:30 UTC
advisory none within the 12-month scanOne wall time, two instants: 02:30 in New_York is 06:30 UTC in August; in Sao_Paulo, 05:30 UTC. New York draws a dated warning — 2027-03-14 has no 02:30 — while Sao Paulo, without DST since 2019, draws none.
@dailynormalized 0 0 * * *
note `@daily` expands to `0 0 * * *`.
sentence At 00:00, every day
next runs 2026-08-16 00:00 UTC · 2026-08-17 00:00 UTC · 2026-08-18 00:00 UTC
note spec.timeZone is unset, so Kubernetes interprets this schedule in the time zone of the kube-controller-manager process — whatever zone that machine runs in. The runs below assume UTC.@daily is shorthand, not a mode — it becomes 0 0 * * * before parsing. Midnight in which zone? Unset, the question has no fixed answer, so the assumption is stated rather than hidden.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
An unset timeZone is a cluster property
Runs follow the kube-controller-manager's zone, not your terminal's. The page states its UTC assumption; wall-clock jobs should carry spec.timeZone.
spec.timeZone needs Kubernetes 1.27
The field is rejected before 1.27, so the generated YAML plants a version comment right beside it.
Day-of-month plus day-of-week means OR
0 8 1 * MON fires on the first and on every Monday — the day fields OR together, so keep one of them *.
Valid syntax can still never run
30 2 30 2 * parses, but February 30th never arrives; an eight-year lookahead says so plainly.
Five macros expand; @reboot is refused
@hourly through @yearly become plain field lines before parsing. Anything else is declined by name — a CronJob controller has no boot moment.
DST advisories carry civil dates
A skip or duplicate warning names the transition date within the next twelve months. Zones without transitions get none.
startingDeadlineSeconds meets missed runs
The deadline bounds how stale a replayed run may start; under 10 seconds runs can drop entirely — the controller reconciles every ten seconds.
Six fields, ? and CRON_TZ= belong elsewhere
Six fields read as Quartz and are refused toward that page; ? is read as * with a warning; CRON_TZ= is declined toward spec.timeZone.
Zone typos get the nearest real name
America/Sao Paulo — space, not underscore — is refused with America/Sao_Paulo suggested. Real clusters match zone names case-sensitively.
Names are DNS-1123, and 52 is the practical cap
Past 52 characters the controller cannot append its 11-character Job suffix; invalid or long names warn here before the cluster refuses.
kubectl create cronjob has no timeZone flag
The imperative command takes --schedule only, so a zone still means editing YAML — here the manifest ships with the field placed.
Common errors
field 3 (day of month): `32` out of range 1–31- Day of month tops out at 31; the message names the failing field by position.
Looks like Quartz (seconds field) — Kubernetes uses 5 fields; try the Quartz tool- A leading seconds column marks Quartz. Drop the first field for Kubernetes, or take the line to the Quartz page unchanged.
`?` is Quartz/EventBridge syntax; Kubernetes treats it the same as `*` — it is treated as `*` here.- A warning, not a rejection — the API server accepts it; ? only carries meaning in Quartz and EventBridge.
Unknown time zone `America/Sao Paulo` — did you mean `America/Sao_Paulo`?- IANA names use underscores, never spaces. The closest valid name rides inside the message, ready to paste.
Schedule is longer than the 512 characters spec.schedule accepts here. To scaffold a CronJob from a shell: kubectl create cronjob hello --image=busybox:1.36 --schedule="*/5 * * * *" --dry-run=client -o yaml- Real schedules are tens of characters — half a kilobyte means the wrong thing was pasted, so the input is refused whole, never truncated.
FAQ
What time zone does a Kubernetes CronJob use if spec.timeZone is not set?
The zone of the kube-controller-manager process on the control plane — usually UTC on managed clusters, but that is convention, not contract. When the wall clock matters, set spec.timeZone explicitly on 1.27 or newer.
Why did my CronJob skip a run or run twice after a DST change?
A schedule pinned to a daylight-saving zone follows that wall clock: a time inside the spring-forward gap does not occur that day, and one inside the fall-back hour occurs twice. Prefer UTC when exactly-once matters.
Which Kubernetes version supports spec.timeZone?
General availability came in 1.27, after a 1.25 beta; older API servers reject the field at admission. That is why the YAML prints a version comment beside timeZone whenever it is present.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Recompute the sentence, runs and manifest immediately.
- ⌘/Ctrl + S
- Download the manifest as cronjob.yaml.
- ⌘/Ctrl + C
- Copy the manifest while nothing is selected.
- ⌘/Ctrl + Shift + C
- Copy the manifest even over an active selection.
- t
- Rotate the theme (idle while typing).
- ? or ⌘/Ctrl + /
- Open the shortcut reference overlay.
- Esc
- Dismiss the topmost overlay.