kubernetes/kops · error

failed to parse objects: %w

Error message

failed to parse objects: %w

What it means

ClientApplier.Apply parses the raw YAML manifest into typed Kubernetes objects via kubemanifest.LoadObjectsFrom before applying them. If the manifest is not valid YAML or an object is malformed, parsing fails and the underlying error is wrapped with this message. Nothing is sent to the cluster.

Source

Thrown at channels/pkg/channels/clientapplier.go:39

	"fmt"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/dynamic"
	"k8s.io/client-go/restmapper"
	"k8s.io/kops/pkg/applylib/applyset"
	"k8s.io/kops/pkg/kubemanifest"
)

type ClientApplier struct {
	Client     dynamic.Interface
	RESTMapper *restmapper.DeferredDiscoveryRESTMapper
}

// Apply applies the manifest to the cluster.
func (p *ClientApplier) Apply(ctx context.Context, manifest []byte) error {
	objects, err := kubemanifest.LoadObjectsFrom(manifest)
	if err != nil {
		return fmt.Errorf("failed to parse objects: %w", err)
	}

	// TODO: Cache applyset for more efficient applying
	patchOptions := metav1.PatchOptions{
		FieldManager: "kops",
	}

	// We force to overcome errors like: Apply failed with 1 conflict: conflict with "kubectl-client-side-apply" using apps/v1: .spec.template.spec.containers[name="foo"].image
	// TODO: How to handle this better?   In a controller we don't have a choice and have to force eventually.
	// But we could do something like try first without forcing, log the conflict if there is one, and then force.
	// This would mean that if there was a loop we could log/detect it.
	// We could even do things like back-off on the force apply.
	force := true
	patchOptions.Force = &force

	s, err := applyset.New(applyset.Options{
		RESTMapper:   p.RESTMapper,
		Client:       p.Client,

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Validate the manifest locally: kubectl apply --dry-run=client -f manifest.yaml or yamllint.
  2. Check for unresolved template placeholders and render templates before calling Apply.
  3. Confirm the fetched data is the actual YAML (not an HTML error page).
  4. Fix YAML indentation/syntax at the position given in the wrapped error.
  5. Regenerate the manifest from the upstream addon source.

Example fix

// before
err := applier.Apply(ctx, manifestBytes) // manifestBytes contains templated {{ .Foo }}
// after
rendered, err := renderTemplate(tmpl, data)
if err != nil { return err }
if err := yaml.Unmarshal(rendered, &struct{}{}); err != nil { return fmt.Errorf("invalid manifest: %w", err) }
err = applier.Apply(ctx, rendered)
Defensive patterns

Strategy: validation

Validate before calling

var raw []map[string]any
if err := yaml.Unmarshal(manifest, &raw); err != nil {
    return fmt.Errorf("manifest is not valid YAML: %w", err)
}
for i, o := range raw {
    if o["apiVersion"] == nil || o["kind"] == nil {
        return fmt.Errorf("object %d missing apiVersion/kind", i)
    }
}

Type guard

func isParseFailure(err error) bool {
    return strings.Contains(err.Error(), "failed to parse objects")
}

Try / catch

if err := applier.Apply(ctx, manifest); err != nil {
    if isParseFailure(err) {
        return fmt.Errorf("fix manifest before applying: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Apply with a manifest containing YAML syntax errors, invalid Kubernetes object structure, unknown/malformed kinds, or non-UTF8 bytes.

Common situations: Hand-edited addon manifests; templating left unresolved placeholders (e.g. {{ }}) in the YAML; wrong file loaded (HTML error page from a failed fetch); schema drift after Kubernetes API changes.

Understand the failure class

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/9bb48ff8dc7c88b5. Report an issue: GitHub.