Fluxtail
Log Management Guides

Kubectl Get Logs: A Practical Guide to Tailing Pods

Master Kubernetes logging with our guide to kubectl get logs (and why it's really 'kubectl logs'). Learn flags, filtering, and real-world debugging workflows.

2026-06-27 kubectl get logs kubernetes logs kubectl devops sre

The correct command is kubectl logs, not Kubectl get logs. kubectl get fetches Kubernetes resource metadata like pods and services, while kubectl logs retrieves a container's runtime stdout and stderr output, which is what you need when a pod is failing and you need answers fast.

If you're here, there's a good chance something is broken right now. A pod won't start, a rollout is hanging, or an app that looked healthy a minute ago is now throwing errors. In that moment, the difference between the wrong command and the right one matters.

This is the practical path often employed in real incidents. Start with one pod. Add live tailing. Filter hard when noise takes over. Then move up to multi-container pods and label selectors when the problem isn't isolated to a single replica. At the end, there's a clear point where the CLI stops being enough.

Table of Contents

Why 'kubectl get logs' Is a Myth

The search phrase Kubectl get logs exists because people naturally combine the command they already know with the thing they want. They use kubectl get pods, kubectl get events, kubectl get svc, so kubectl get logs feels like it should work. It doesn't.

The Kubernetes CLI treats these as different categories of operations. kubectl get asks the API for resource information. kubectl logs asks for container output. The Kubernetes kubectl logs reference makes that distinction explicit: kubectl get logs is syntactically invalid, while kubectl logs prints logs for a container in a pod or another specified resource.

What get does and what logs does

A quick comparison helps:

Command What it returns Good for
kubectl get pods Resource state and metadata Seeing whether a pod exists, is running, pending, or restarting
kubectl describe pod <pod> Events, conditions, and config details Understanding scheduling, image pull, probe, and restart context
kubectl logs <pod> Container stdout and stderr Seeing what the application actually emitted

When a rollout fails, don't stay at the metadata layer longer than needed. get tells you that something is wrong. logs helps you find why.

Practical rule: Run kubectl get pods to locate the problem, then switch to kubectl logs as soon as you know which workload is misbehaving.

One more trap catches newer engineers. If your app writes to a file inside the container instead of standard streams, kubectl logs won't show the output you expect. Kubernetes surfaces stdout and stderr by default through this command, so application logging behavior matters just as much as the CLI syntax.

Your First Look into a Pod's Logs

The first useful command is still the simplest one:

kubectl logs <pod-name>

That gives you the current log output for the default container in that pod. Under the hood, kubectl logs is the standard CLI path for retrieving container logs directly from pods by streaming stdout and stderr output, and the -f flag enables real-time follow mode for live troubleshooting, as noted in this Stack Overflow explanation of continuous kubectl log streaming.

A focused young developer working on code in a clean home office environment on his computer.

Start with the pod name

If you already know the exact pod:

kubectl logs api-7d8f6c7b9f-rxk2m

If you don't, get it first:

kubectl get pods
kubectl logs api-7d8f6c7b9f-rxk2m

What you'll see depends on the app. Sometimes it's obvious. A stack trace, a failed database connection, a missing environment variable. Sometimes it's just startup chatter. Either way, you're now looking at the process output instead of guessing from pod status alone.

If log streams still feel noisy, it helps to get better at reading patterns before you chase flags. This short guide on how to read logs effectively is worth passing to anyone new to on-call work.

Stay attached during a live failure

Static output is useful when the failure already happened. During a rollout or an active incident, follow mode is usually better:

kubectl logs -f api-7d8f6c7b9f-rxk2m

That behaves like tail -f. New lines appear as the container writes them.

Use it when:

  • Watching startup: Confirm whether the app binds its port, runs migrations, or exits immediately.
  • Testing a fix: Trigger a request while the stream is open and watch what the service logs.
  • Following readiness issues: Keep the terminal attached while probes fail and recover.

A small habit saves time here. Open one terminal for kubectl get pods -w and another for kubectl logs -f. One shows pod lifecycle changes. The other shows what the process is doing. Together they give you enough signal for most first-pass debugging.

If a deployment is unstable, live tailing usually tells you more than repeated one-off log pulls.

Filtering Logs to Find the Signal

Raw log dumps get expensive fast. Not in money first. In attention. The terminal fills, the useful line scrolls away, and now you're reading everything except the thing that matters.

The fix is to narrow the time window or the volume before you start reading. The SFEIR kubectl debugging cheatsheet calls out two flags that matter constantly in production work: --since for time-based filtering and --previous for the logs from a crashed container instance.

Use time and line limits first

Start with the recent window that matches the incident.

kubectl logs <pod-name> --since=1h

That pulls logs from the last hour. If the issue started after a deployment or a config change, this cuts out the old noise.

Then control the amount of text:

kubectl logs <pod-name> --tail=100

--tail=100 gets the last 100 lines. If you omit --tail, Kubernetes can stream all available logs in the local buffer, typically up to the last 10 MB or 5 log rotations, which is exactly how people overwhelm their own terminal during an incident. That behavior is described in this kubectl logs deployment guide.

A solid default pattern looks like this:

kubectl logs <pod-name> --since=1h --tail=100

That command is often enough to answer the first question: did the app start failing recently, or has it been broken for longer, unnoticed?

Use previous logs for crash loops

Crash loops are where newer engineers lose time. They run kubectl logs <pod-name>, get little or nothing, and assume the command isn't helping. The reason is simpler. The current container instance restarted, so the output you need is from the last run.

Use this instead:

kubectl logs <pod-name> --previous

That pulls logs from the container instance that crashed and restarted. For CrashLoopBackOff, this is often the first command that gives you the error.

A realistic sequence looks like this:

  1. You see restarts: kubectl get pods
  2. You confirm the pattern: kubectl describe pod <pod-name>
  3. You inspect the crashed run: kubectl logs <pod-name> --previous

Typical findings include bad startup flags, failed secrets loading, migrations that can't connect, or the app exiting before readiness probes ever succeed.

When a pod is in CrashLoopBackOff, check --previous before you spend time tailing the current instance.

If the issue is recent but recurring, combine the flags:

kubectl logs <pod-name> --previous --since=1h

That gives you a tighter view of the failed run without dumping the entire buffer.

Advanced Logging for Microservices

Single-pod debugging is the easy part. Distributed systems get messy because the failing component isn't always the one emitting the clearest symptom. A sidecar may be noisy. One replica may be bad while the others look healthy. Query the wrong target and you'll conclude the system is fine when it isn't.

A diagram illustrating three stages of advanced logging for microservices: multi-container pods, centralized logging, and structured logging.

Isolate the right container

In multi-container pods, be explicit:

kubectl logs <pod-name> -c <container-name>

That -c flag matters. In practice, app containers, proxies, agents, and sidecars all produce different noise profiles. If you're trying to debug the application and you accidentally read the proxy logs, you'll burn time on the wrong stream.

For teams working in sidecar-heavy setups, this deeper piece on microservices logging patterns is worth keeping in your internal docs.

A common workflow:

  • App issue: kubectl logs api-abc123 -c app
  • Proxy issue: kubectl logs api-abc123 -c envoy
  • Collector issue: kubectl logs api-abc123 -c log-shipper

The same Plural guide on deployment logging notes that -c <container-name> is mandatory for isolation in multi-container pods, because mixing containers adds noise and hurts error correlation.

Here's a quick visual before going further:

Aggregate pods with labels

Once a service has multiple replicas, targeting one pod can hide the underlying issue. The useful move is to stream logs from all matching pods with a label selector:

kubectl logs -l app=api-server

That pattern is especially useful when:

Situation Better target
One pod keeps restarting Individual pod name
Errors appear across a whole service Label selector like -l app=api-server
You need logs from a specific container across pods Label selector plus -c <container-name>

The same deployment guide explains that querying a deployment object directly only returns logs from a single pod, while label selectors aggregate the pods of interest. In practice, that difference is huge during a production incident.

For a multi-container service running several replicas, make the command precise:

kubectl logs -l app=api-server -c app

Add shell filtering carefully

Once you're selecting the right pods and containers, shell tools become useful again:

kubectl logs -l app=api-server -c app | grep ERROR

Or live:

kubectl logs -f -l app=api-server -c app | grep timeout

This is effective for short-lived debugging sessions. It is not a substitute for proper aggregation, structured logging, or retention. It also won't magically order events across pods in a perfect timeline. You still need judgment when several replicas emit overlapping output.

How to Fix Common Kubectl Logs Errors

When kubectl logs fails, the command usually isn't the primary problem. The surrounding context is. Wrong namespace. Wrong container. Wrong assumptions about where the app writes logs. Missing RBAC. These are the failures that eat time because the terminal output looks small but the underlying mistake is operational.

A troubleshooting guide for kubectl logs errors covering pods, containers, log output, and connection issues.

Pod not found usually means namespace

The first check is boring and often correct. You're in the wrong namespace.

kubectl logs <pod-name> -n <namespace>

In clusters with separate environments, kubectl logs defaults to the default namespace unless you specify another one. The kubectl logs command reference is the canonical place to confirm syntax and available flags, and namespace mistakes are one of the most common reasons people think the pod doesn't exist.

Run these together when in doubt:

kubectl get pods -n <namespace>
kubectl logs <pod-name> -n <namespace>

No output often means the app is logging wrong

If the container is running but the logs are empty, check the application behavior before you blame Kubernetes.

Common causes include:

  • Logs go to a file: kubectl logs won't show /var/log/app.log unless something forwards it to stdout or stderr.
  • The wrong container is selected: In multi-container pods, you may be looking at a quiet sidecar.
  • The pod never really started: A failing init path or immediate crash can leave you with little current output.

The CLI can only show what the container actually emits to standard streams.

If your team owns the service, fix this at the app layer. Write logs to stdout and stderr, keep the format consistent, and avoid burying critical errors in container-local files that disappear with the pod.

Permission problems are usually RBAC

When the error says forbidden, stop trying variants of the same command. Check access.

A practical checklist:

  1. Confirm identity: Make sure you're using the kubeconfig context you think you are.
  2. Confirm namespace scope: Your access may differ between namespaces.
  3. Check log permissions: kubectl auth can-i get pods/log -n <namespace>
  4. Escalate cleanly: Ask for the minimum RBAC needed, not blanket admin rights.

Permission failures are operational issues, not syntax issues. Treat them that way and you'll resolve them faster.

When Kubectl Logs Is Not Enough

kubectl logs is one of the best tactical tools in Kubernetes. It's fast, direct, and available almost everywhere. It also has limits that show up the moment an incident crosses pod boundaries or outlives the node buffer.

Screenshot from https://fluxtail.io

The limits show up fast in real incidents

The first limit is retention. If you rely only on kubectl logs, you're reading what the node still has. As noted earlier, that can be the local buffer rather than a durable history, and it disappears with pod churn, rescheduling, and node loss.

The second limit is correlation. A production issue rarely stays inside one pod. You may need app logs, ingress logs, worker logs, and some surrounding system behavior in the same investigation. The CLI can help you sample those streams, but it doesn't become a coherent incident workspace on its own.

The third limit is continuity. Follow mode is useful, but it doesn't stay useful across every restart and rollout pattern. During high churn, engineers start opening more terminals, copying fragments into chat, and rebuilding the timeline manually.

What a centralized platform fixes

A centralized logging platform solves a different class of problem than kubectl logs solves.

Use the CLI when you need immediate answers from a specific workload. Move to centralized log management when you need:

  • Persistence: Logs survive pod restarts, reschedules, and cluster churn.
  • Search across services: One query can span application, platform, and supporting components.
  • Cleaner live tailing: Teams can watch active incidents without juggling many terminals.
  • Shared investigation context: Engineers and incident commanders work from the same data.
  • Operational guardrails: Alerts, analytics, and chat-based queries become possible on top of the logs.

If you're designing that next layer, this guide to log management best practices is a useful reference point.

At that stage, kubectl logs doesn't go away. It just returns to its proper role. First response, spot checks, and pod-level validation.


Fluxtail gives teams a centralized place to ingest, separate, search, and live-tail logs without turning incidents into a terminal juggling exercise. If you need durable streams, readable triage views, analytics, alerts, and chat-based log queries through MCP-compatible AI clients, take a look at Fluxtail.