Skip to content

kubectl explain writes partial output to stdout when the field path is invalid #1872

Description

@ManafovM

What happened:
kubectl explain <type>.<invalid-field> still prints the KIND/VERSION header to stdout before it fails. The error itself goes to stderr and the exit code is 1, but stdout isn't empty, so a failed command still produces output that looks like a real result.

What you expected to happen:
A command that fails shouldn't write anything to stdout. Scripts treat stdout as the result, so the leftover header ends up in redirects, pipes, and $(...) as if the command had worked. On failure, only the stderr message and the non-zero exit code should show up.

How to reproduce it (as minimally and precisely as possible):

# stdout is non-empty even though the command fails:
$ kubectl explain pods.spec.nonexistentfield 2>/dev/null; echo "exit=$?"
KIND:       Pod
VERSION:    v1

exit=1

# same with --recursive:
$ kubectl explain pods.spec.nonexistentfield --recursive 2>/dev/null; echo "exit=$?"
KIND:       Pod
VERSION:    v1

exit=1

An invalid top-level type doesn't have this problem; it fails before rendering, so stdout stays empty:

$ kubectl explain nosuchresource 2>/dev/null; echo "exit=$?"
exit=1

Anything else we need to know?:
The explain v2 renderer writes the template straight to the output writer. The KIND/VERSION header (in pkg/explain/v2/templates/plaintext.tmpl) is written before the field path is walked, and the "field does not exist" error only fires partway through rendering, so by then the header is already on stdout.

Environment:

  • Kubernetes client and server versions (use kubectl version): Client v1.36.1 (also reproduces on master, v1.38.0-alpha.0); server v1.36.1
  • Cloud provider or hardware configuration: kind
  • OS (e.g: cat /etc/os-release): macOS, but it's not platform-specific

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

kind/bugCategorizes issue or PR as related to a bug.triage/acceptedIndicates an issue or PR is ready to be actively worked on.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions