Your CronJob was supposed to run a scheduled task, but when you check the status, you see failed executions or no jobs were created at all. CronJobs are useful for periodic tasks like backups, report generation, and cleanup, but they can fail due to schedule misconfigurations, job template issues, or concurrency problems.

Understanding CronJob Failures

CronJobs create Jobs at specified times based on a cron schedule. Each Job then creates Pods to execute the task. Failures can occur at several levels: the CronJob schedule might be wrong, the Job template might have configuration issues, the Pods might fail to start, or the actual task might fail during execution.

The key is understanding which level is failing - the CronJob, the Job, or the Pod.

Diagnosis Commands

Start by checking the CronJob status:

```bash # List CronJobs kubectl get cronjobs -n namespace

# Check CronJob details kubectl describe cronjob cronjob-name -n namespace

# Check recent jobs created by CronJob kubectl get jobs -n namespace -l cronjob-name=cronjob-name

# Check CronJob events kubectl get events -n namespace --field-selector involvedObject.name=cronjob-name ```

Check job execution:

```bash # Check job status kubectl get jobs -n namespace

# Describe failed job kubectl describe job job-name -n namespace

# Check job pods kubectl get pods -n namespace -l job-name=job-name

# Check job logs kubectl logs job/job-name -n namespace ```

Check schedule format:

bash
# Get CronJob schedule
kubectl get cronjob cronjob-name -n namespace -o jsonpath='{.spec.schedule}'

Common Solutions

Solution 1: Fix Cron Schedule Syntax

The schedule might be incorrect, preventing jobs from being created:

```bash # Common schedule format: "MIN HOUR DOM MON DOW" # Example: "0 * * * *" runs every hour at minute 0

# Check your schedule kubectl get cronjob cronjob-name -n namespace -o yaml | grep schedule ```

Common schedule mistakes:

```yaml # Schedule syntax examples spec: schedule: "0 * * * *" # Every hour schedule: "*/15 * * * *" # Every 15 minutes schedule: "0 0 * * *" # Daily at midnight schedule: "0 0 * * 0" # Weekly on Sunday schedule: "0 0 1 * *" # Monthly on 1st

# Wrong: "60 * * * *" - minutes must be 0-59 # Wrong: "* * * * * *" - too many fields (Kubernetes uses 5 fields, not 6) # Wrong: "@daily" - Kubernetes doesn't support @ syntax ```

Verify schedule interpretation:

bash
# Use a cron schedule parser online or locally
# Test your schedule: https://crontab.guru/

Solution 2: Fix Job Template Issues

The job template might prevent pod creation:

```yaml # Check job template kubectl get cronjob cronjob-name -n namespace -o yaml | grep -A 50 jobTemplate

# Common issues: # - Wrong image name # - Missing/incorrect command # - Resource limits too high # - Missing environment variables ```

Fix job template:

yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: my-cronjob
spec:
  schedule: "0 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: task
            image: correct-image:tag  # Verify image exists
            command: ["sh", "-c", "echo 'Task running' && actual-command"]
            # Ensure command is correct
          restartPolicy: OnFailure  # Or Never

Solution 3: Fix Failed Job Execution

Jobs might fail during execution:

```bash # Check job failure reason kubectl describe job job-name -n namespace | grep -A 10 "Status:|Conditions"

# Check pod logs for failure kubectl logs job/job-name -n namespace

# If pod failed, check previous logs kubectl logs pod-name -n namespace --previous ```

Fix job failures:

```yaml # Adjust backoff limit (how many retries before marking failed) jobTemplate: spec: backoffLimit: 3 # Default 6, can reduce or increase

# Adjust active deadline (max time job can run) activeDeadlineSeconds: 600 # Job fails after 10 minutes

# Add proper error handling in command template: spec: containers: - name: task command: ["sh", "-c", "your-command || echo 'Failed with code $?' && exit 1"] ```

Solution 4: Fix Concurrency Policy

Multiple jobs might conflict based on concurrency settings:

bash
# Check concurrency policy
kubectl get cronjob cronjob-name -n namespace -o jsonpath='{.spec.concurrencyPolicy}'

Concurrency policy options:

```yaml spec: # Allow: Run concurrent jobs (default) concurrencyPolicy: Allow

# Forbid: Skip new job if previous still running concurrencyPolicy: Forbid

# Replace: Replace previous job with new one concurrencyPolicy: Replace ```

If jobs are skipped due to Forbid policy:

```bash # Check if previous job is still running kubectl get jobs -n namespace

# Check events for skipped jobs kubectl get events -n namespace | grep -i "skipped"

# Adjust job timeout to complete faster spec: jobTemplate: spec: activeDeadlineSeconds: 300 # Reduce job duration ```

Solution 5: Fix Starting Deadline Seconds

Jobs might be skipped due to starting deadline:

```yaml # If CronJob misses its scheduled time, this limits how late it can start spec: startingDeadlineSeconds: 300 # Job must start within 5 minutes of schedule

# If set too low, jobs might be skipped if controller is busy # Increase if needed: spec: startingDeadlineSeconds: 600 # More lenient deadline ```

Check missed schedules:

bash
# Look for "Missed scheduled time" in events
kubectl get events -n namespace | grep -i "missed\|schedule"

Solution 6: Fix Successful Jobs History Limit

Too many completed jobs can cause issues:

```yaml # Control how many completed/failed jobs to keep spec: successfulJobsHistoryLimit: 3 # Default 3 failedJobsHistoryLimit: 1 # Default 1

# If too many jobs accumulate, increase limit or clean up manually kubectl delete jobs -n namespace -l cronjob-name=my-cronjob --field-selector status.successful=1 ```

Solution 7: Check CronJob Controller Status

The CronJob controller might have issues:

```bash # Check controller manager status (on control plane) kubectl get pods -n kube-system -l component=kube-controller-manager

# Check controller logs kubectl logs -n kube-system kube-controller-manager-master | grep -i cronjob ```

Solution 8: Fix Pod Restart Policy

Pod restart policy affects job behavior:

yaml
jobTemplate:
  spec:
    template:
      spec:
        restartPolicy: OnFailure  # Pod restarts on failure
        # Or:
        restartPolicy: Never      # Pod doesn't restart, job creates new pod

Solution 9: Fix Service Account and RBAC

Job might need permissions:

```yaml jobTemplate: spec: template: spec: serviceAccountName: job-service-account

# Create role for job apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: job-role rules: - apiGroups: [""] resources: ["pods", "secrets"] verbs: ["get", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: job-rolebinding subjects: - kind: ServiceAccount name: job-service-account roleRef: kind: Role name: job-role apiGroup: rbac.authorization.k8s.io ```

Solution 10: Manual Trigger for Testing

Trigger job manually to test:

```bash # Create job from CronJob template manually kubectl create job --from=cronjob/my-cronjob test-job -n namespace

# Check the test job kubectl get job test-job -n namespace kubectl logs job/test-job -n namespace

# Clean up test job kubectl delete job test-job -n namespace ```

Verification

After fixing the issue:

```bash # Check CronJob is creating jobs kubectl get cronjob cronjob-name -n namespace

# Monitor job creation kubectl get jobs -n namespace -w

# Check job execution kubectl describe job latest-job -n namespace

# Verify job pods complete kubectl get pods -n namespace -l job-name=latest-job

# Check job logs kubectl logs job/latest-job -n namespace ```

CronJob Troubleshooting Flow

bash
CronJob failed or not creating jobs
            |
            v
Is schedule correct?
            |
            +-- No --> Fix schedule syntax
            |
            +-- Yes --> Are jobs being created?
                        |
                        +-- No --> Check controller, startingDeadline
                        |
                        +-- Yes --> Check job status
                                    |
                                    +-- Pending --> Resource/image issue
                                    |
                                    +-- Failed --> Check pod logs
                                    |
                                    +-- Complete --> Success!

CronJob Failure Causes Summary

CauseSymptomsSolution
Wrong scheduleNo jobs createdFix cron syntax (5 fields)
Image pull failPods in ErrImagePullFix image name/registry
Command errorPods complete with errorFix command in job template
Concurrency ForbidJobs skippedChange policy or job duration
Starting deadlineJobs skipped when busyIncrease startingDeadlineSeconds
RBAC blockedPermission deniedAdd service account and role
Resource limitsPods pendingAdjust resource requests
Active deadlineJobs timeoutIncrease activeDeadlineSeconds

Prevention Best Practices

Test schedules with online cron validators before deploying. Use manual triggers to test job templates before enabling schedule. Set appropriate backoff limits for retry behavior. Configure concurrency policy based on job requirements. Monitor job completion with alerts. Set reasonable activeDeadlineSeconds to prevent hung jobs. Clean up old jobs regularly. Use proper logging to capture job output.

CronJob failures usually trace back to the schedule syntax, job template configuration, or the actual task failing. Manual triggering with kubectl create job --from=cronjob/... is the fastest way to test if your job template works before debugging the schedule.