derailed/k9s · info

stream closed: %w for %s

Error message

stream closed: %w for %s

What it means

readLogs treats io.EOF as the clean end of the log stream: it flushes any trailing partial line, emits this ErrLogItem, and returns streamEOF (which stops the retry loop — only streamError retries). It is informational: the reader consumed everything the server sent and the connection closed normally.

Source

Thrown at internal/dao/pod.go:522

				}
			}
			continue
		}

		if droppedLines > 0 {
			slog.Warn("Total log lines dropped during stream",
				slogs.Container, opts.Info(),
				slogs.Count, droppedLines,
			)
		}

		if errors.Is(err, io.EOF) {
			if len(bytes) > 0 {
				// Emit trailing partial line before EOF
				out <- opts.ToLogItem(tview.EscapeBytes(bytes))
			}
			slog.Debug("Log reader reached EOF", slogs.Container, opts.Info())
			out <- opts.ToErrLogItem(fmt.Errorf("stream closed: %w for %s", err, opts.Info()))
			return streamEOF
		}

		// Non-EOF error
		slog.Debug("Log stream error, will retry connection",
			slogs.Container, opts.Info(),
			slogs.Error, fmt.Errorf("stream error: %w for %s", err, opts.Info()),
		)
		return streamError
	}
}

// MetaFQN returns a fully qualified resource name.
func MetaFQN(m *metav1.ObjectMeta) string {
	if m.Namespace == "" {
		return m.Name
	}

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Treat it as normal end-of-stream, not a failure
  2. Use follow mode if the stream must stay open across container restarts
  3. If logs end unexpectedly, check restart count and previous logs (kubectl logs -p)
Defensive patterns

Strategy: try-catch

Try / catch

for item := range podDAO.Logs(ctx, opts) {
    if item.IsErr && strings.Contains(item.Message, "stream closed") && strings.Contains(item.Message, "EOF") {
        break // normal end of stream: finalize UI, do not show as error
    }
}

Prevention

When it happens

Trigger: A non-follow log request reaching the end of output; a container exiting while logs are tailed; the server closing the stream after container termination.

Common situations: Reading logs of Completed Job pods without follow; containers restarting mid-tail; short-lived pods whose logs end as soon as the process finishes.

Related errors


AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15). Data as JSON: /api/errors/1108e998fe9a1745. Report an issue: GitHub.