kubernetes/kops · error

addon spec is not configured for %q

Error message

addon spec is not configured for %q

What it means

AddonManifest.Normalize validates that the internal addonSpec field has been populated before doing any manifest processing. addonSpec is set when the addon manifest task is built from the bootstrap channel builder; if it is nil, subsequent steps (remapping, hashing, pruning) could not work, so kOps aborts with this message naming the addon.

Source

Thrown at upup/pkg/fi/cloudup/bootstrapchannelbuilder/addonmanifest.go:78

)

// GetDependencies makes the addon wait for every non-addon task, so templates that reach into
// the task graph see fully realized state. Intentionally pessimistic: addon rendering is fast
// enough that over-depending is not worth the footgun of under-declaring.
func (a *AddonManifest) GetDependencies(tasks map[string]fi.CloudupTask) []fi.CloudupTask {
	dependencies := make([]fi.CloudupTask, 0, len(tasks))
	for _, task := range tasks {
		if isAddonTask(task) {
			continue
		}
		dependencies = append(dependencies, task)
	}
	return dependencies
}

func (a *AddonManifest) Normalize(c *fi.CloudupContext) error {
	if a.addonSpec == nil {
		return fmt.Errorf("addon spec is not configured for %q", fi.ValueOf(a.Name))
	}
	if a.source == nil {
		return fmt.Errorf("addon source is not configured for %q", fi.ValueOf(a.Name))
	}

	manifestBytes, err := fi.ResourceAsBytes(a.source)
	if err != nil {
		return fmt.Errorf("error reading addon %q manifest: %v", fi.ValueOf(a.Name), err)
	}

	if !a.skipRender && a.addonRenderer != nil {
		manifestBytes, err = a.addonRenderer.RenderTemplate(fi.ValueOf(a.Location), manifestBytes, tasksVisibleToAddons(c.AllTasks()))
		if err != nil {
			return fmt.Errorf("error rendering addon %q template: %w", fi.ValueOf(a.Name), err)
		}
	}

	if !a.skipRemap {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the code path that constructs this AddonManifest in bootstrapchannelbuilder and ensure addonSpec (built from the channel's addons.AddonSpec) is assigned before Normalize runs
  2. If you added a new addon, follow the existing builder pattern: buildAddonManifest(..., spec, ...) so the spec is wired in
  3. In tests, populate the spec field (or use the package builder helper) rather than a bare struct literal
  4. Verify with go test ./upup/pkg/fi/cloudup/bootstrapchannelbuilder/... to see which addon name is reported and trace its builder call

Example fix

// before
m := &AddonManifest{Name: fi.PtrTo("coredns"), source: res}
// after
m := &AddonManifest{Name: fi.PtrTo("coredns"), source: res, addonSpec: spec}
where spec := &addons.AddonSpec{Name: fi.PtrTo("coredns.addons.k8s.io"), ...}
Defensive patterns

Strategy: validation

Validate before calling

if m.addonSpec == nil {
    return fmt.Errorf("addon %s: addonSpec must be set before Normalize", fi.ValueOf(m.Name))
}

Type guard

func (a *AddonManifest) HasSpec() bool { return a.addonSpec != nil }

Prevention

When it happens

Trigger: Normalize runs (during CloudupContext task normalization, exercised by TestAddonManifestNormalizeSkipsRenderForRawSources / TestAddonManifestNormalizeRendersTemplateSources) on an AddonManifest that was created via a constructor or struct literal that never called the setter for addonSpec — e.g. a builder path that set a.source but skipped building the addons.AddonSpec.

Common situations: A newly added addon in bootstrapchannelbuilder whose AddonManifest is constructed with an incomplete builder chain; a refactor renaming/moving the spec-building method so it is no longer called; test code building AddonManifest by hand without the spec.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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