kubernetes/kops · error
error reading addon %q: %v
Error message
error reading addon %q: %v
What it means
After resolving the addon location to a URL, LoadClusterAddon reads the addon manifest bytes through the VFS context. Any ReadFile failure (not-found, permission denied, TLS/network errors, bad credentials) is wrapped as this error with the resolved URL and underlying cause.
Source
Thrown at pkg/clusteraddons/load.go:46
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
}
// ParseClusterAddon parses a ClusterAddon object
func ParseClusterAddon(raw []byte) (*ClusterAddon, error) {
objects, err := kubemanifest.LoadObjectsFrom(raw)
if err != nil {
return nil, fmt.Errorf("error parsing addon %v", err)
}
return &ClusterAddon{Raw: string(raw), Objects: objects}, nilView on GitHub (pinned to 4c8573c808)
Solutions
- Verify the addon URL/exists: open the resolved location in a browser or curl it; fix the path if 404.
- Check VFS credentials and network access for the backend hosting the addon.
- Pin the addon location to a version-matched URL for your kops/Kubernetes version.
Example fix
// before addon, err := LoadClusterAddon(vfs.Context, "https://addons.k8s.io/v1.28/networking.yaml") // 404 // after addon, err := LoadClusterAddon(vfs.Context, "https://addons.k8s.io/stable/networking.yaml")
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight reachability check
if err := probeURL(resolvedLocation); err != nil {
return fmt.Errorf("addon location unreachable before create: %v", err)
} Try / catch
addon, err := LoadClusterAddon(vfs.Context, loc)
if err != nil {
if strings.Contains(err.Error(), "error reading addon") {
return retryWithBackoff(func() (*ClusterAddon, error) { return LoadClusterAddon(vfs.Context, loc) })
}
return err
} Prevention
- Curl/GET the addon URL before cluster creation.
- Verify VFS/cloud credentials for private addon stores.
- Pin addon URLs to version-matched stable locations.
When it happens
Trigger: LoadClusterAddon called (from RunCreateCluster) with a location that resolves to a nonexistent file, a private bucket without credentials, a DNS/network failure, or an HTTP 404 on the addon URL.
Common situations: Kubernetes version-mismatched addon URLs that no longer exist upstream; offline/restricted networks during cluster creation; misconfigured S3/VFS credentials; typos in addon file names.
Related errors
- error loading channel %q: %v
- reading kops-channels manifest %s: %w
- error downloading file %q: %v
- error reading %s %q: %v
- error reading %s: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/67c45c60e4fd9e5b.
Report an issue: GitHub.