kubernetes/kops · error

invalid addon location: %q

Error message

invalid addon location: %q

What it means

LoadClusterAddon parses the addon location string as a URL before resolving it via VFS. If url.Parse rejects the string (control characters, invalid percent-escapes, etc.) the addon location is reported as invalid. This happens before any network/VFS access.

Source

Thrown at pkg/clusteraddons/load.go:37

import (
	"fmt"
	"net/url"

	"k8s.io/klog/v2"
	"k8s.io/kops/pkg/kubemanifest"
	"k8s.io/kops/util/pkg/vfs"
)

type ClusterAddon struct {
	Raw     string
	Objects kubemanifest.ObjectList
}

// LoadClusterAddon loads a set of objects from the specified VFS location
func LoadClusterAddon(vfsContext *vfs.VFSContext, location string) (*ClusterAddon, error) {
	u, err := url.Parse(location)
	if err != nil {
		return nil, fmt.Errorf("invalid addon location: %q", location)
	}

	// TODO: Should we support relative paths for "standard" addons?  See equivalent code in LoadChannel

	resolved := u.String()
	klog.V(2).Infof("Loading addon from %q", resolved)
	addonBytes, err := vfsContext.ReadFile(resolved)
	if err != nil {
		return nil, fmt.Errorf("error reading addon %q: %v", resolved, err)
	}
	addon, err := ParseClusterAddon(addonBytes)
	if err != nil {
		return nil, fmt.Errorf("error parsing addon %q: %v", resolved, err)
	}
	klog.V(4).Infof("Addon contents: %s", string(addonBytes))

	return addon, nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Correct the addon location string in the cluster/channel manifest so it is a valid URL or absolute path.
  2. URL-encode special characters (spaces -> %20, etc.) in the location.
  3. Remove the broken addon entry and re-add it using the canonical addon location from the kops addons repo.

Example fix

// before
addon, err := LoadClusterAddon(vfs.Context, "https://addons.k8s.io/ networking addon")
// after
addon, err := LoadClusterAddon(vfs.Context, "https://addons.k8s.io/networking-addon.yaml")
Defensive patterns

Strategy: validation

Validate before calling

if _, err := url.Parse(location); err != nil {
  return fmt.Errorf("addon location %q is not a valid URL: %v", location, err)
}

Try / catch

addon, err := LoadClusterAddon(vfs.Context, loc)
if err != nil && strings.Contains(err.Error(), "invalid addon location") {
  return fmt.Errorf("fix addons entry in cluster spec: %w", err)
}

Prevention

When it happens

Trigger: Calling LoadClusterAddon with a location string that is not a parsable URL — e.g. contains spaces or raw control bytes, malformed % sequences (like %zz), or is otherwise corrupt in the channel/cluster manifest.

Common situations: Hand-edited cluster spec addons lists with typos; copy-pasted locations with invisible characters; addon locations with unencoded special characters.

Related errors


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