A pod status shows: NAME READY STATUS RESTARTS AGE payment-api-7d9f8 0/1 CrashLoopBackOff 7 12m
What does CrashLoopBackOff mean, and what should you check first?
CrashLoopBackOff is not itself the root cause — it's Kubernetes describing its own restart behaviour: the container starts, exits (crashes or the entrypoint process ends), and Kubernetes restarts it, waiting longer each cycle (backoff) to avoid hammering a broken container.
Diagnosis order: 1. kubectl logs <pod> --previous — logs from the crashed container (the running one may have no output yet) 2. kubectl describe pod <pod> — check the Last State section for an exit code 3. Common exit codes: 1 generic application error, 137 = SIGKILL (often OOMKilled), 139 = segfault, 143 = SIGTERM (graceful shutdown, unusual if crash-looping) 4. Check Events at the bottom of describe pod for scheduler-level clues
Common root causes: missing environment variable causing the app to exit on startup, failing readiness/liveness probe with an aggressive failureThreshold, or a missing config file/secret mount.
OOMKilled ("Out Of Memory Killed") means the container tried to use more memory than its configured resources.limits.memory, so the Linux kernel's OOM killer terminated the process — this always maps to exit code 137 (128 + signal 9 / SIGKILL).
Investigation steps: • kubectl top pod worker-3f2a1 — current memory usage vs. limit • Check whether memory usage grows steadily over the pod's lifetime (memory leak) or spikes suddenly (a large batch job or unbounded cache) • Compare requests vs limits — a limit set too close to normal usage causes frequent OOMKills under load
Fixes: raise the memory limit if the workload is legitimately memory-hungry, add pagination/streaming to avoid loading large datasets into memory, or fix a leak (unclosed connections, growing in-memory cache without eviction).
Do not confuse with CPU throttling — that shows up as slow performance, not termination, and is visible via container_cpu_cfs_throttled_periods_total.
3 / 5
A teammate asks you to explain this line from kubectl get events: Warning FailedScheduling pod/api-6b7c9 0/5 nodes are available: 3 Insufficient memory, 2 node(s) had taint {dedicated: gpu} that the pod didn't tolerate.
How would you summarise this to the team in plain English?
FailedScheduling events describe why the scheduler cannot place a pod on any node — this is a pre-flight issue, before the container ever starts, so kubectl logs will show nothing (no container exists yet).
Reading the message: • 0/5 nodes are available — the scheduler evaluated 5 nodes and none were suitable • 3 Insufficient memory — 3 nodes don't have enough allocatable memory left for this pod's requests.memory • 2 node(s) had taint {dedicated: gpu} — 2 nodes are tainted to repel general workloads (commonly used to reserve expensive GPU nodes); this pod has no matching toleration, so it's excluded
Fixes: lower the pod's memory request, scale up the node pool, or add a toleration if the pod is actually meant to run on the GPU nodes. This kind of scheduling failure vocabulary — taints, tolerations, node affinity — is essential for describing capacity problems clearly in incident channels.
4 / 5
kubectl logs api-gateway-5f9d2 -c sidecar returns an error: Error from server (BadRequest): container "sidecar" in pod "api-gateway-5f9d2" is waiting to start: PodInitializing
What does this tell you, and what command would you use instead?
The -c flag targets a specific container within a multi-container pod. PodInitializing means one or more init containers — special containers that run to completion before the main containers start — are still executing (common uses: waiting for a dependency, running a database migration, fetching a config file).
Diagnosis: • kubectl describe pod api-gateway-5f9d2 — the Init Containers section shows each init container's status • kubectl logs api-gateway-5f9d2 -c <init-container-name> — logs from a specific init container (they're named separately from app containers) • If an init container is stuck, the whole pod stays in Init:0/1-style status and none of the app containers start
Multi-container pod vocabulary:init container (runs once, before app containers), sidecar (runs alongside the main container for its whole lifetime — e.g. a log shipper or service mesh proxy), ephemeral container (injected temporarily for debugging a running pod).
5 / 5
You run kubectl logs -f deploy/notifications-service --since=10m and see repeated lines: {"level":"WARN","msg":"readiness probe failed: connection refused","port":8080}
The pod's STATUS is Running but READY shows 0/1. What's the most accurate explanation?
Running but not Ready is a distinct and common state: the container process exists (so STATUS = Running) but Kubernetes won't route traffic to it because the readiness probe is failing.
Probe vocabulary: • Liveness probe — "is the process alive?" Failing this restarts the container. • Readiness probe — "can this pod handle traffic right now?" Failing this removes the pod from the Service's endpoints (no restart) — used during slow startup or temporary overload. • Startup probe — gives slow-starting apps extra time before liveness/readiness checks begin.
"Connection refused" specifically means the TCP handshake failed — no process is listening on that port at all (different from a timeout, which means something is listening but not responding). Likely causes: the app is still initialising (loading config, warming caches, connecting to a database), the probe targets the wrong port, or the app crashed and is mid-restart internally without the container exiting.
Communicating this precisely — "it's a readiness failure, not a crash" — saves teammates from chasing the wrong root cause during an incident.
What will I practise in "Reading Kubernetes Logs — Log Reading Exercises"?
Practice reading kubectl logs, pod crash logs, OOMKilled events, and CrashLoopBackOff states. Diagnose scheduling failures, init container issues, and readiness probe failures. 5 exercises for DevOps and SRE engineers.
How many exercises are in this module?
This module has 5 multiple-choice exercises, each with instant feedback and a full explanation of the correct answer.
Is this exercise free to use?
Yes. Every exercise on CoderSlingo, including this one, is free to use with no account, sign-up, or paywall.
Do I need to create an account to do these exercises?
No account is required. Just click an option to answer — your score for this session is tracked automatically in the progress bar above.
What happens if I choose the wrong answer?
You'll immediately see which answer was correct, plus a full explanation covering the vocabulary and reasoning behind it — mistakes are where most of the learning happens.
Can I retry the exercises if I want a higher score?
Yes — use the "Try again" button on the results screen to reset and go through all the questions again.
Is my progress saved if I close the page?
No. Progress is tracked only for your current visit; reloading or leaving the page resets the counter. This keeps the exercise simple and account-free.
Where can I find more Log Reading exercises?
Browse the full Log Reading hub for related drills, or check the "Next up" link below to continue with a connected topic.
How is this different from reading an article on the same topic?
Articles explain vocabulary and concepts in prose; this exercise tests and reinforces that vocabulary through active recall with immediate feedback — the two work best together.
Who writes these exercises?
Every exercise is written by the CoderSlingo team, drawing on real workplace English used in IT roles, then reviewed for accuracy and clarity.