{"record":{"id":"808c660e44c7cfdb","repo":"helm/helm","slug":"failed-to-stream-pod-logs-for-pod-s-container","errorCode":null,"errorMessage":"failed to stream pod logs for pod: %s, container: %s","messagePattern":"failed to stream pod logs for pod: (.+?), container: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/kube/client.go","lineNumber":1308,"sourceCode":"\tfor _, pod := range podList.Items {\n\t\tfor _, container := range pod.Spec.Containers {\n\t\t\toptions := &v1.PodLogOptions{\n\t\t\t\tContainer: container.Name,\n\t\t\t}\n\t\t\trequest := c.kubeClient.CoreV1().Pods(namespace).GetLogs(pod.Name, options)\n\t\t\terr2 := copyRequestStreamToWriter(request, pod.Name, container.Name, writerFunc(namespace, pod.Name, container.Name))\n\t\t\tif err2 != nil {\n\t\t\t\treturn err2\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc copyRequestStreamToWriter(request *rest.Request, podName, containerName string, writer io.Writer) error {\n\treadCloser, err := request.Stream(context.Background())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to stream pod logs for pod: %s, container: %s\", podName, containerName)\n\t}\n\tdefer readCloser.Close()\n\t_, err = io.Copy(writer, readCloser)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to copy IO from logs for pod: %s, container: %s\", podName, containerName)\n\t}\n\treturn nil\n}\n\n// scrubValidationError removes kubectl info from the message.\nfunc scrubValidationError(err error) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\tconst stopValidateMessage = \"if you choose to ignore these errors, turn validation off with --validate=false\"\n\n\tif strings.Contains(err.Error(), stopValidateMessage) {\n\t\treturn errors.New(strings.ReplaceAll(err.Error(), \"; \"+stopValidateMessage, \"\"))","sourceCodeStart":1290,"sourceCodeEnd":1326,"githubUrl":"https://github.com/helm/helm/blob/2a29f1770b62844b27197d2507377361d45ad7c0/pkg/kube/client.go#L1290-L1326","documentation":"Thrown by copyRequestStreamToWriter (pkg/kube/client.go:1308) when opening the log stream for a pod/container fails: the rest.Request.Stream call backing pod log retrieval (used by OutputContainerLogsForPodList to dump logs of non-ready pods when a --wait fails). Notably this error is formatted without %w — the underlying cause (404, 403, container not running) is discarded, so only pod and container names are reported.","triggerScenarios":"helm --wait fails and Helm tries to print pod logs, but the stream fails: pod already terminated/evicted (logs unavailable for stopped containers in some runtimes), RBAC missing pods/log, container in CrashLoopBackOff with no log endpoint yet, or kubelet/apiserver log path errors.","commonSituations":"Debugging failed --wait installs where RBAC grants pods list but not pods/log; pods deleted between readiness check and log fetch; ephemeral/exit-early containers (jobs) whose logs are gone by fetch time.","solutions":["Fetch logs directly to see the real cause: kubectl logs <pod> -c <container> -n <namespace> --previous.","Grant pods/log to the identity if kubectl logs returns 403 for the same service account.","Treat this error as secondary: it occurs while reporting the primary --wait failure — fix the pod's readiness problem (image, probes, crashloop) first.","For flapping pods, collect logs via cluster-level tooling or kubectl logs -f since Helm's one-shot fetch may race pod deletion."],"exampleFix":"# before: helm --wait fails, log dump errors with no cause\n# 'failed to stream pod logs for pod: app-abc123, container: web'\n\n# after: reproduce with kubectl to surface the real status\nkubectl logs app-abc123 -c web -n default --previous\nkubectl auth can-i get pods/log -n default","handlingStrategy":"try-catch","validationCode":"// Skip log fetching for pods in terminal phases\nfor _, pod := range podList.Items {\n    if pod.Status.Phase == v1.PodSucceeded || pod.Status.Phase == v1.PodFailed {\n        continue // log stream for terminal pods may be unavailable\n    }\n    fetchLogs(pod)\n}","typeGuard":"func isLogStreamError(err error) bool {\n    return strings.Contains(err.Error(), \"failed to stream pod logs for pod:\")\n}","tryCatchPattern":"if err := client.OutputContainerLogsForPodList(pods, ns, wf); err != nil {\n    if isLogStreamError(err) {\n        // note: Helm drops the cause here; fall back to direct kubectl logs\n        // never mask the primary wait failure with this\n    }\n    return err\n}","preventionTips":["Grant pods/log alongside pods/list in any role used with --wait.","Treat this error as diagnostic noise: always fix the underlying readiness failure shown by the primary --wait error.","For crashlooping jobs, collect logs with --previous or cluster log tooling instead of relying on Helm's one-shot dump."],"tags":["kubernetes","pod-logs","rbac","debugging","helm"],"backgroundTag":null,"analyzedSha":"2a29f1770b62844b27197d2507377361d45ad7c0","analyzedAt":"2026-08-15T22:02:47.490Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}