Docker
Kubernetes
CrashLoopBackOff
ContainerDebugging
DevOps

How to exec into a container and view file if container is in CrashLoopBackOff state

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

You usually cannot rely on kubectl exec when a container is in CrashLoopBackOff, because the process may exit before you can attach to it. The right debugging sequence is: inspect logs and events first, then use a debug container, a replacement pod, or a temporary command override depending on what you need to inspect.

Start with Evidence, Not exec

Before trying to open a shell, inspect why the pod is crashing.

bash
1kubectl get pods
2kubectl describe pod my-pod
3kubectl logs my-pod
4kubectl logs my-pod --previous

--previous is especially important because it shows logs from the last crashed container instance, which is often exactly the information you need.

Why kubectl exec Often Fails Here

kubectl exec needs a running container. In CrashLoopBackOff, the container may:

  • crash immediately
  • restart too quickly to attach
  • fail before the shell binary is even available for you to use

If the process survives long enough, you can still try:

bash
kubectl exec -it my-pod -- sh

But for a fast crash loop, that is unreliable.

Use kubectl debug When Available

A common solution is to attach an ephemeral debug container to the pod.

bash
kubectl debug -it pod/my-pod --image=busybox --target=my-container

This gives you a separate debugging container in the pod's namespaces, which is often enough to inspect mounted volumes, environment, and network state.

It is one of the cleanest modern approaches because it avoids changing the original application image just to debug it.

If You Need the Same Image, Start a Sleep Pod

Sometimes you need to inspect files that exist only in the crashing image itself. In that case, run a new pod from the same image but override the command so it stays alive.

bash
1kubectl run debug-copy \
2  --image=my-registry/my-image:tag \
3  --restart=Never \
4  --command -- sleep 3600

Then attach:

bash
kubectl exec -it debug-copy -- sh

This is useful for checking config files, application bundles, and startup scripts baked into the image.

Copy Files Out Instead of Shelling In

If you only need one file and the container lives long enough momentarily, kubectl cp can help.

bash
kubectl cp my-pod:/app/config.yml ./config.yml

However, if the container crashes too quickly, a debug pod from the same image is more reliable than racing a restart loop.

Override the Command Temporarily

If the pod is managed by a Deployment and you control the workload, temporarily change the command so the container stays alive for inspection.

Example pattern:

yaml
command: ["sh", "-c", "sleep 3600"]

After applying that temporary change, the pod stays up, and you can inspect its filesystem with kubectl exec. This is intrusive, so use it carefully and revert it once debugging is done.

Mounted Volumes Are Often the Real Target

If the file you care about lives on a mounted volume, you do not always need the crashing container at all. A separate debug pod mounting the same PersistentVolumeClaim can inspect the data without racing the crash loop.

That is often safer than modifying the original workload.

A practical order of operations:

  1. read describe and both current and previous logs
  2. inspect the container command, args, probes, and environment
  3. use kubectl debug if supported
  4. if needed, run a new pod from the same image with a long sleep command
  5. only then consider patching the Deployment temporarily

This keeps the original workload stable while still giving you access to the relevant files.

Common Pitfalls

The biggest mistake is trying kubectl exec repeatedly without checking logs and events first. Another is assuming CrashLoopBackOff is the root cause when it is really just Kubernetes reporting repeated failure. Teams also often forget kubectl logs --previous, which is one of the most valuable commands in this situation. Finally, patching the live Deployment for debugging without a rollback plan can create confusion if the temporary debug command is accidentally left in place.

Summary

  • 'kubectl exec often fails in CrashLoopBackOff because the container is not stable enough to attach to.'
  • Start with describe, current logs, and --previous logs.
  • Use kubectl debug or a replacement pod from the same image for filesystem inspection.
  • Override the command only when you control the workload and need a temporary live shell.
  • Debug the underlying crash, not just the Kubernetes status label.

Course illustration
Course illustration

All Rights Reserved.