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:
# 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:
# 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:
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 NeverSolution 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:
# 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:
# 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:
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure # Pod restarts on failure
# Or:
restartPolicy: Never # Pod doesn't restart, job creates new podSolution 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
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
| Cause | Symptoms | Solution |
|---|---|---|
| Wrong schedule | No jobs created | Fix cron syntax (5 fields) |
| Image pull fail | Pods in ErrImagePull | Fix image name/registry |
| Command error | Pods complete with error | Fix command in job template |
| Concurrency Forbid | Jobs skipped | Change policy or job duration |
| Starting deadline | Jobs skipped when busy | Increase startingDeadlineSeconds |
| RBAC blocked | Permission denied | Add service account and role |
| Resource limits | Pods pending | Adjust resource requests |
| Active deadline | Jobs timeout | Increase 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.