kubernetes/kops · error

rendering addon %q for image discovery: %w

Error message

rendering addon %q for image discovery: %w

What it means

CollectImages renders each addon manifest (unless SkipRender) with renderer.RenderTemplate in order to discover container images before remapping. If template rendering fails, the error is wrapped with the addon key so the failing addon can be identified.

Source

Thrown at upup/pkg/fi/cloudup/bootstrapchannelbuilder/bootstrapchannelbuilder.go:302

}

// CollectImages renders template sources under stubbed task funcs and scans
// the resulting YAML for image references to pre-register with the builder.
// Best-effort only (used for AWS WarmPool image prewarm): a failure here
// warns rather than breaks the build.
func (a *Addon) CollectImages(assetBuilder *assets.AssetBuilder, renderer AddonTemplateRenderer) error {
	if a == nil || assetBuilder == nil || a.Source == nil {
		return nil
	}

	manifestBytes, err := fi.ResourceAsBytes(a.Source)
	if err != nil {
		return err
	}
	if !a.SkipRender && renderer != nil {
		manifestBytes, err = renderer.RenderTemplate(addonKey(a.Spec), manifestBytes, nil)
		if err != nil {
			return fmt.Errorf("rendering addon %q for image discovery: %w", addonKey(a.Spec), err)
		}
	}
	_, err = assetBuilder.RemapManifest(manifestBytes)
	return err
}

func (b *BootstrapChannelBuilder) buildAddons(c *fi.CloudupModelBuilderContext) (*AddonList, map[types.NamespacedName]iam.Subject, error) {
	addons := &AddonList{}

	serviceAccountRoles := []iam.Subject{}

	{
		key := "kops-controller.addons.k8s.io"

		{
			location := key + "/k8s-1.16.yaml"
			id := "k8s-1.16"

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the wrapped error from RenderTemplate for the template syntax problem
  2. Fix the Go-template syntax in the addon manifest at the named addon key
  3. Set the addon as a raw source (SkipRender) if it needs no templating
  4. Upgrade/downgrade kops so template functions match the channel

Example fix

// before (addon template)
image: {{ .Image }}
// after: balanced, valid template
image: "{{ .Image }}"
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check template balance before CollectImages
if bytes.Count(manifestBytes, []byte("{{")) != bytes.Count(manifestBytes, []byte("}}")) {
    return fmt.Errorf("addon %s has unbalanced template delimiters", addonKey(a.Spec))
}

Try / catch

if err := a.CollectImages(ctx, renderer, assetBuilder); err != nil {
    if strings.Contains(err.Error(), "rendering addon") {
        var rerr error
        errors.As(err, &rerr) // wrapped RenderTemplate error
        klog.Errorf("fix template for addon %s: %v", addonKey(a.Spec), err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling CollectImages on a channel whose addon manifest is a template containing invalid Go-template constructs or functions the renderer cannot evaluate; addon has SkipRender=false and a non-nil renderer.

Common situations: Hand-edited addon templates with unbalanced {{ }}; templates referencing functions removed in a kops upgrade; custom addon channels built with the wrong template syntax.

Related errors


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