πŸ“šBook Signing at KubeCon EU 2026Meet us at Booking.com HQ (Mon 18:30-21:00) & vCluster booth #521 (Tue 24 Mar, 12:30-1:30pm) β€” free book giveaway!RSVP Booking.com Event
Troubleshooting beginner ⏱ 8 minutes K8s 1.28+

kubectl describe: Read Pod Events Guide

Use kubectl describe pod to read events, conditions, and container states. Diagnose scheduling failures, image pulls, crashes, and probe failures.

By Luca Berton β€’ β€’ πŸ“– 5 min read

πŸ’‘ Quick Answer: kubectl describe pod <name> shows the full pod lifecycle: container states, conditions, events, resource requests, volumes, and node assignment. Scroll to the Events section at the bottom for the diagnostic gold β€” it shows scheduling decisions, image pulls, container starts, probe failures, and OOM kills in chronological order.

The Problem

kubectl get pods shows status but not why:

NAME      READY   STATUS             RESTARTS   AGE
my-pod    0/1     CrashLoopBackOff   5          3m

What crashed? Why? When? You need kubectl describe for the full story.

The Solution

Read the Events Section

kubectl describe pod my-pod

# Scroll to the bottom:
# Events:
#   Type     Reason     Age   From               Message
#   ----     ------     ----  ----               -------
#   Normal   Scheduled  3m    default-scheduler  Successfully assigned default/my-pod to worker-1
#   Normal   Pulling    3m    kubelet            Pulling image "myapp:latest"
#   Normal   Pulled     2m    kubelet            Successfully pulled image
#   Normal   Created    2m    kubelet            Created container my-app
#   Normal   Started    2m    kubelet            Started container my-app
#   Warning  Unhealthy  1m    kubelet            Readiness probe failed: HTTP probe failed with statuscode: 503
#   Warning  BackOff    30s   kubelet            Back-off restarting failed container

Common Event Patterns

Scheduling failure:

Warning  FailedScheduling  default-scheduler  0/3 nodes are available:
  1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane:},
  2 node(s) didn't match Pod's node affinity/selector

Image pull failure:

Warning  Failed     kubelet  Failed to pull image "myapp:v2": rpc error:
  code = NotFound desc = failed to pull and unpack image: not found
Warning  Failed     kubelet  Error: ImagePullBackOff

OOM Kill:

Warning  OOMKilling  kubelet  Memory cgroup out of memory: Killed process 12345
Normal   Killing     kubelet  Stopping container my-app

Probe failure:

Warning  Unhealthy  kubelet  Liveness probe failed: HTTP probe failed with statuscode: 500
Normal   Killing    kubelet  Container my-app failed liveness probe, will be restarted

Key Sections in Describe Output

kubectl describe pod my-pod

# 1. Metadata
# Name, Namespace, Node, Labels, Annotations

# 2. Status & Conditions
# Status:    Running
# Conditions:
#   Type              Status
#   Initialized       True
#   Ready             False    ← Pod not serving traffic
#   ContainersReady   False
#   PodScheduled      True

# 3. Container Details
# Container ID, Image, State (Running/Waiting/Terminated)
# Last State: Terminated (exit code, reason, signal)
# Restart Count, Resource Requests/Limits
# Liveness/Readiness probe config
# Environment variables, Mounts

# 4. Volumes
# ConfigMap, Secret, PVC references

# 5. Events (most recent last)
# Chronological lifecycle events

Describe Other Resources

# Node (capacity, allocatable, conditions, taints)
kubectl describe node worker-1

# Service (endpoints, selector matches)
kubectl describe svc my-service

# Deployment (replicas, rollout status, events)
kubectl describe deployment my-app

# PVC (bound status, storage class, events)
kubectl describe pvc my-data

# Events only (all namespace events)
kubectl get events --sort-by='.lastTimestamp'
kubectl get events -A --field-selector reason=FailedScheduling

Scripting with Events

# Get events as JSON for automation
kubectl get events -o json | jq '.items[] | select(.reason == "OOMKilling") | {pod: .involvedObject.name, time: .lastTimestamp}'

# Watch events in real time
kubectl get events -w

# Events for a specific pod
kubectl get events --field-selector involvedObject.name=my-pod

Common Issues

β€œEvents:”

Events expire after 1 hour by default. If the pod has been running longer, events may have been garbage collected. Check kubectl get events for recent cluster events.

Describe shows β€œPending” with no events

Scheduler hasn’t processed the pod yet. Wait a few seconds β€” if still no events, the scheduler may be overloaded or down.

Multiple containers β€” which one failed?

Each container has its own section in describe output with individual State, Last State, and Restart Count.

Best Practices

  • Always read Events section first β€” it tells the chronological story
  • Check Conditions for Ready/NotReady β€” explains why traffic isn’t routing
  • Compare Requests vs Node capacity β€” for scheduling failures
  • Use kubectl get events --sort-by for cluster-wide troubleshooting
  • kubectl logs <pod> --previous complements describe β€” events show what, logs show why

Key Takeaways

  • kubectl describe pod is the primary troubleshooting command
  • Events section at the bottom shows the complete lifecycle chronology
  • Common patterns: FailedScheduling, ImagePullBackOff, OOMKilling, probe failures
  • Events expire after 1 hour β€” check quickly after issues occur
  • Combine with kubectl logs --previous for full diagnosis
#kubectl #troubleshooting #events #cka #pods
Luca Berton
Written by Luca Berton

Principal Solutions Architect specializing in Kubernetes, AI/GPU infrastructure, and cloud-native platforms. Author of Kubernetes Recipes and creator of CopyPasteLearn courses.

Kubernetes Recipes book cover

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens