Skip to main content
governance · kubernetes

Active CronJobs that have never started a single run

resource types
1
rule IDs covered
3
severity
medium

What does ZopNight detect here?

ZopNight flags a Kubernetes CronJob on EKS, GKE or AKS that is not suspended, has no `status.lastScheduleTime`, and is older than its expected first run: 48 hours for daily or faster schedules, 8 days for weekly, 32 days for monthly and 366 days for yearly ones. Such a CronJob exists but has done nothing.

Signal and threshold

How ZopNight evaluates Active CronJobs that have never started a single run.
Field Value
Rule IDsRC-1734 · RC-1834 · RC-1934
Categorygovernance
Severitymedium
Metricstatus.lastScheduleTime
Thresholdabsent, CronJob older than 48h to 366d depending on schedule
SourceZopNight
Permissions usedlist cronjobs.batch

A CronJob that never fires is a silent failure

The CronJob controller records when it last created a Job in status.lastScheduleTime, which the CronJob API reference describes as the last time the job was successfully scheduled. A CronJob with no value there has never launched anything. Nobody gets paged, because nothing failed: the backup, report or cleanup the CronJob was written for simply never ran.

The usual causes are in the scheduling rules on the CronJob concepts page. A startingDeadlineSeconds below 10 seconds can stop the job being scheduled at all, because the controller only checks every 10 seconds. More than 100 missed schedules makes the controller skip the run and log too many missed start times. A schedule written for the wrong time zone can also put the first run much later than expected, since a CronJob without .spec.timeZone uses the controller manager’s local zone.

Spotting CronJobs with no run on record

Terminal window
kubectl get cronjobs -A -o json | jq -r '
.items[]
| select(.spec.suspend != true and .status.lastScheduleTime == null)
| "\(.metadata.namespace)/\(.metadata.name) \(.spec.schedule) created=\(.metadata.creationTimestamp)"'

For any hit, kubectl describe cronjob <name> shows controller events such as missed-start warnings.

The age gate scales with the schedule

A CronJob created yesterday for a monthly report has not failed; its first run is not due yet. ZopNight therefore reads the cron expression and waits longer for slower schedules:

Terminal window
@yearly, @annually, or a specific month set -> 366 days old before flagging
@monthly, or a specific day of month -> 32 days
@weekly, or a specific day of week -> 8 days
@daily, @hourly, anything more frequent -> 48 hours
unrecognised expressions -> 48 hours

Age is measured from the CronJob’s creation timestamp. If that timestamp is missing or cannot be parsed, the rule stays silent rather than guess.

Where the check steps aside

Suspended CronJobs are skipped here, because pausing is a deliberate choice covered by Suspended CronJob. Any CronJob with a lastScheduleTime, even a very old one, is also skipped: this rule is about never having run, not about runs that stopped.

Governance finding, not a saving

The recommendation carries no dollar figure. An idle CronJob object costs nothing to keep; the risk is the missing work and the false confidence that it is happening.

Getting the first run to happen

  1. Print the schedule with kubectl get cronjob <name> -o jsonpath='{.spec.schedule}' and check the expression and, if set, .spec.timeZone.
  2. Look at startingDeadlineSeconds. Unset it or raise it well above 10 seconds.
  3. Trigger a test run from the template with kubectl create job <name>-manual --from=cronjob/<name> and confirm it succeeds.
  4. If the work is no longer needed, delete the CronJob so the inventory reflects what runs.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

472 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

472 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·